Skip to content

Commit b7914df

Browse files
authored
[clang-tidy] add default error message for performance-avoid-endl (#107867)
use std::endl as default message when matched expr does not have valid source text Fixes: #107859
1 parent c6c3803 commit b7914df

File tree

3 files changed

+33
-15
lines changed

3 files changed

+33
-15
lines changed

clang-tools-extra/clang-tidy/performance/AvoidEndlCheck.cpp

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -46,38 +46,41 @@ void AvoidEndlCheck::check(const MatchFinder::MatchResult &Result) {
4646
// Handle the more common streaming '... << std::endl' case
4747
const CharSourceRange TokenRange =
4848
CharSourceRange::getTokenRange(Expression->getSourceRange());
49-
const StringRef SourceText = Lexer::getSourceText(
49+
StringRef SourceText = Lexer::getSourceText(
5050
TokenRange, *Result.SourceManager, Result.Context->getLangOpts());
51-
51+
if (SourceText.empty())
52+
SourceText = "std::endl";
5253
auto Diag = diag(Expression->getBeginLoc(),
5354
"do not use '%0' with streams; use '\\n' instead")
5455
<< SourceText;
55-
56-
Diag << FixItHint::CreateReplacement(TokenRange, "'\\n'");
56+
if (TokenRange.isValid())
57+
Diag << FixItHint::CreateReplacement(TokenRange, "'\\n'");
5758
} else {
5859
// Handle the less common function call 'std::endl(...)' case
5960
const auto *CallExpression = llvm::cast<CallExpr>(Expression);
6061
assert(CallExpression->getNumArgs() == 1);
6162

62-
const StringRef SourceText = Lexer::getSourceText(
63+
StringRef SourceText = Lexer::getSourceText(
6364
CharSourceRange::getTokenRange(
6465
CallExpression->getCallee()->getSourceRange()),
6566
*Result.SourceManager, Result.Context->getLangOpts());
67+
if (SourceText.empty())
68+
SourceText = "std::endl";
69+
auto Diag = diag(CallExpression->getBeginLoc(),
70+
"do not use '%0' with streams; use '\\n' instead")
71+
<< SourceText;
6672

6773
const CharSourceRange ArgTokenRange = CharSourceRange::getTokenRange(
6874
CallExpression->getArg(0)->getSourceRange());
6975
const StringRef ArgSourceText = Lexer::getSourceText(
7076
ArgTokenRange, *Result.SourceManager, Result.Context->getLangOpts());
71-
72-
const std::string ReplacementString =
73-
std::string(ArgSourceText) + " << '\\n'";
74-
75-
diag(CallExpression->getBeginLoc(),
76-
"do not use '%0' with streams; use '\\n' instead")
77-
<< SourceText
78-
<< FixItHint::CreateReplacement(
79-
CharSourceRange::getTokenRange(CallExpression->getSourceRange()),
80-
ReplacementString);
77+
const CharSourceRange ReplacementRange =
78+
CharSourceRange::getTokenRange(CallExpression->getSourceRange());
79+
if (!ArgSourceText.empty() && ReplacementRange.isValid()) {
80+
const std::string ReplacementString =
81+
std::string(ArgSourceText) + " << '\\n'";
82+
Diag << FixItHint::CreateReplacement(ReplacementRange, ReplacementString);
83+
}
8184
}
8285
}
8386

clang-tools-extra/docs/ReleaseNotes.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,10 @@ Changes in existing checks
123123
<clang-tidy/checks/modernize/use-std-print>` check to support replacing
124124
member function calls too.
125125

126+
- Improved :doc:`performance-avoid-endl
127+
<clang-tidy/checks/performance/avoid-endl>` check to use ``std::endl`` as
128+
placeholder when lexer cannot get source text.
129+
126130
- Improved :doc:`readability-implicit-bool-conversion
127131
<clang-tidy/checks/readability/implicit-bool-conversion>` check
128132
by adding the option `UseUpperCaseLiteralSuffix` to select the

clang-tools-extra/test/clang-tidy/checkers/performance/avoid-endl.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,3 +225,14 @@ void bad_custom_stream() {
225225
// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: do not use 'std::endl' with streams; use '\n' instead [performance-avoid-endl]
226226
// CHECK-FIXES: logger << '\n';
227227
}
228+
229+
namespace gh107859 {
230+
231+
#define ENDL std::endl;
232+
233+
void bad_macro() {
234+
std::cout << ENDL;
235+
// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: do not use 'std::endl' with streams; use '\n' instead [performance-avoid-endl]
236+
}
237+
238+
} // namespace gh107859

0 commit comments

Comments
 (0)