Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[clang-tidy] add default error message for performance-avoid-endl #107867

33 changes: 18 additions & 15 deletions clang-tools-extra/clang-tidy/performance/AvoidEndlCheck.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,38 +46,41 @@ void AvoidEndlCheck::check(const MatchFinder::MatchResult &Result) {
// Handle the more common streaming '... << std::endl' case
const CharSourceRange TokenRange =
CharSourceRange::getTokenRange(Expression->getSourceRange());
const StringRef SourceText = Lexer::getSourceText(
StringRef SourceText = Lexer::getSourceText(
TokenRange, *Result.SourceManager, Result.Context->getLangOpts());

if (SourceText.empty())
SourceText = "std::endl";
auto Diag = diag(Expression->getBeginLoc(),
"do not use '%0' with streams; use '\\n' instead")
<< SourceText;

Diag << FixItHint::CreateReplacement(TokenRange, "'\\n'");
if (TokenRange.isValid())
Diag << FixItHint::CreateReplacement(TokenRange, "'\\n'");
HerrCai0907 marked this conversation as resolved.
Show resolved Hide resolved
} else {
// Handle the less common function call 'std::endl(...)' case
const auto *CallExpression = llvm::cast<CallExpr>(Expression);
assert(CallExpression->getNumArgs() == 1);

const StringRef SourceText = Lexer::getSourceText(
StringRef SourceText = Lexer::getSourceText(
CharSourceRange::getTokenRange(
CallExpression->getCallee()->getSourceRange()),
*Result.SourceManager, Result.Context->getLangOpts());
if (SourceText.empty())
SourceText = "std::endl";
auto Diag = diag(CallExpression->getBeginLoc(),
"do not use '%0' with streams; use '\\n' instead")
<< SourceText;

const CharSourceRange ArgTokenRange = CharSourceRange::getTokenRange(
CallExpression->getArg(0)->getSourceRange());
const StringRef ArgSourceText = Lexer::getSourceText(
ArgTokenRange, *Result.SourceManager, Result.Context->getLangOpts());

const std::string ReplacementString =
std::string(ArgSourceText) + " << '\\n'";

diag(CallExpression->getBeginLoc(),
"do not use '%0' with streams; use '\\n' instead")
<< SourceText
<< FixItHint::CreateReplacement(
CharSourceRange::getTokenRange(CallExpression->getSourceRange()),
ReplacementString);
const CharSourceRange ReplacementRange =
CharSourceRange::getTokenRange(CallExpression->getSourceRange());
if (!ArgSourceText.empty() && ReplacementRange.isValid()) {
const std::string ReplacementString =
std::string(ArgSourceText) + " << '\\n'";
Diag << FixItHint::CreateReplacement(ReplacementRange, ReplacementString);
}
}
}

Expand Down
4 changes: 4 additions & 0 deletions clang-tools-extra/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,10 @@ Changes in existing checks
<clang-tidy/checks/modernize/use-std-print>` check to support replacing
member function calls too.

- Improved :doc:`performance-avoid-endl
<clang-tidy/checks/performance/avoid-endl>` check to use ``std::endl`` as
placeholder when lexer cannot get source text.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds better IMO

as a default when the lexer can not retrieve the source text.


- Improved :doc:`readability-implicit-bool-conversion
<clang-tidy/checks/readability/implicit-bool-conversion>` check
by adding the option `UseUpperCaseLiteralSuffix` to select the
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -225,3 +225,14 @@ void bad_custom_stream() {
// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: do not use 'std::endl' with streams; use '\n' instead [performance-avoid-endl]
// CHECK-FIXES: logger << '\n';
}

namespace gh107859 {

#define ENDL std::endl;

void bad_macro() {
std::cout << ENDL;
SimplyDanny marked this conversation as resolved.
Show resolved Hide resolved
// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: do not use 'std::endl' with streams; use '\n' instead [performance-avoid-endl]
}

} // namespace gh107859
Loading