[clang-tools-extra] [clang-tidy] Fix invalid fix-it for macro expansions (PR #227984)

Peiqi Li via cfe-commits cfe-commits at lists.llvm.org
Thu Oct 1 00:23:34 PDT 2026


https://github.com/voyager-jhk created https://github.com/llvm/llvm-project/pull/227984

Do not offer a fix-it for one-character strings from macro expansions.

Fixes #222970

>From ba90c5aab9d3709126a94173a1e1e44516f36e8a Mon Sep 17 00:00:00 2001
From: voyager-jhk <voyager.lpq at gmail.com>
Date: Thu, 1 Oct 2026 15:20:28 +0800
Subject: [PATCH] [clang-tidy] Fix invalid fix-it for macro expansions

Do not offer a fix-it for one-character strings from macro expansions.

Fixes #222970
---
 .../performance/PreferSingleCharOverloadsCheck.cpp  | 13 ++++++++-----
 clang-tools-extra/docs/ReleaseNotes.md              |  5 +++++
 .../performance/prefer-single-char-overloads.cpp    | 10 ++++++++++
 3 files changed, 23 insertions(+), 5 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/performance/PreferSingleCharOverloadsCheck.cpp b/clang-tools-extra/clang-tidy/performance/PreferSingleCharOverloadsCheck.cpp
index d5d1784c0a0b7..a62ef1254e806 100644
--- a/clang-tools-extra/clang-tidy/performance/PreferSingleCharOverloadsCheck.cpp
+++ b/clang-tools-extra/clang-tidy/performance/PreferSingleCharOverloadsCheck.cpp
@@ -101,11 +101,14 @@ void PreferSingleCharOverloadsCheck::check(
   if (!Replacement)
     return;
 
-  diag(Literal->getBeginLoc(), "%0 called with a string literal consisting of "
-                               "a single character; consider using the more "
-                               "efficient overload accepting a character")
-      << FindFunc
-      << FixItHint::CreateReplacement(Literal->getSourceRange(), *Replacement);
+  const auto Diag = diag(Literal->getBeginLoc(),
+                         "%0 called with a string literal consisting of "
+                         "a single character; consider using the more "
+                         "efficient overload accepting a character")
+                    << FindFunc;
+  if (!Literal->getBeginLoc().isMacroID() && !Literal->getEndLoc().isMacroID())
+    Diag << FixItHint::CreateReplacement(Literal->getSourceRange(),
+                                         *Replacement);
 }
 
 } // namespace clang::tidy::performance
diff --git a/clang-tools-extra/docs/ReleaseNotes.md b/clang-tools-extra/docs/ReleaseNotes.md
index 5ad0b2d3718b9..84cffb9fe4222 100644
--- a/clang-tools-extra/docs/ReleaseNotes.md
+++ b/clang-tools-extra/docs/ReleaseNotes.md
@@ -257,6 +257,11 @@ infrastructure are described first, followed by tool-specific sections.
   offered when an argument covers only part of a macro expansion, as it then
   has no source text of its own.
 
+- Improved {doc}`performance-prefer-single-char-overloads
+  <clang-tidy/checks/performance/prefer-single-char-overloads>` check to
+  avoid offering fix-its for string literals originating from macro
+  expansions.
+
 - Improved {doc}`readability-convert-member-functions-to-static
   <clang-tidy/checks/readability/convert-member-functions-to-static>` check by
   fixing a crash when checking a const-qualified method declared with the
diff --git a/clang-tools-extra/test/clang-tidy/checkers/performance/prefer-single-char-overloads.cpp b/clang-tools-extra/test/clang-tidy/checkers/performance/prefer-single-char-overloads.cpp
index 46bbf3c20f8fd..14af39aded0b6 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/performance/prefer-single-char-overloads.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/performance/prefer-single-char-overloads.cpp
@@ -146,6 +146,16 @@ int Macros() {
   // CHECK-MESSAGES: [[@LINE-2]]:37: warning: 'find' called with a string literal
 }
 
+#define TOKEN_SEPARATING_CHARACTER "_"
+// CHECK-FIXES: #define TOKEN_SEPARATING_CHARACTER "_"
+
+void foo() {
+  std::string a;
+  a += TOKEN_SEPARATING_CHARACTER;
+  // CHECK-MESSAGES: [[@LINE-1]]:8: warning: 'operator+=' called with a
+  // CHECK-FIXES: a += TOKEN_SEPARATING_CHARACTER;
+}
+
 void SubstitutedTemplateType() {
   Wrapper<std::string>().value.find("a");
   // CHECK-MESSAGES: [[@LINE-1]]:37: warning: 'find' called with a string literal



More information about the cfe-commits mailing list