mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-18 17:56:50 +00:00
[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
This commit is contained in:
parent
c6c3803b72
commit
b7914dffd6
@ -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'");
|
||||
} 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
|
||||
- Improved :doc:`readability-implicit-bool-conversion
|
||||
<clang-tidy/checks/readability/implicit-bool-conversion>` check
|
||||
by adding the option `UseUpperCaseLiteralSuffix` to select the
|
||||
|
@ -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;
|
||||
// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: do not use 'std::endl' with streams; use '\n' instead [performance-avoid-endl]
|
||||
}
|
||||
|
||||
} // namespace gh107859
|
||||
|
Loading…
x
Reference in New Issue
Block a user