[clang-tools-extra] b7914df - [clang-tidy] add default error message for performance-avoid-endl (#107867)

via cfe-commits cfe-commits at lists.llvm.org
Fri Sep 13 16:33:09 PDT 2024


Author: Congcong Cai
Date: 2024-09-14T07:33:06+08:00
New Revision: b7914dffd6eacfa20990a39aecd1e0d24cadc62b

URL: https://github.com/llvm/llvm-project/commit/b7914dffd6eacfa20990a39aecd1e0d24cadc62b
DIFF: https://github.com/llvm/llvm-project/commit/b7914dffd6eacfa20990a39aecd1e0d24cadc62b.diff

LOG: [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

Added: 
    

Modified: 
    clang-tools-extra/clang-tidy/performance/AvoidEndlCheck.cpp
    clang-tools-extra/docs/ReleaseNotes.rst
    clang-tools-extra/test/clang-tidy/checkers/performance/avoid-endl.cpp

Removed: 
    


################################################################################
diff  --git a/clang-tools-extra/clang-tidy/performance/AvoidEndlCheck.cpp b/clang-tools-extra/clang-tidy/performance/AvoidEndlCheck.cpp
index 8ecaa41754fb2b..a394f5c6efa2a4 100644
--- a/clang-tools-extra/clang-tidy/performance/AvoidEndlCheck.cpp
+++ b/clang-tools-extra/clang-tidy/performance/AvoidEndlCheck.cpp
@@ -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);
+    }
   }
 }
 

diff  --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index 8c22d283963f1e..88b92830fda6b4 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -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

diff  --git a/clang-tools-extra/test/clang-tidy/checkers/performance/avoid-endl.cpp b/clang-tools-extra/test/clang-tidy/checkers/performance/avoid-endl.cpp
index 462b88773d231c..df5ff56c827f7f 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/performance/avoid-endl.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/performance/avoid-endl.cpp
@@ -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


        


More information about the cfe-commits mailing list