Author: Peiqi Li Date: 2026-10-08T15:33:03+08:00 New Revision: 66cc20a0b4356d2b5d2278e68bfe5b16ad4e87dd
URL: https://github.com/llvm/llvm-project/commit/66cc20a0b4356d2b5d2278e68bfe5b16ad4e87dd DIFF: https://github.com/llvm/llvm-project/commit/66cc20a0b4356d2b5d2278e68bfe5b16ad4e87dd.diff LOG: [clang-tidy] Fix invalid fix-it for macro expansions (#227984) Do not offer a fix-it for one-character strings from macro expansions. Fixes #222970 Added: Modified: clang-tools-extra/clang-tidy/performance/PreferSingleCharOverloadsCheck.cpp clang-tools-extra/docs/ReleaseNotes.md clang-tools-extra/test/clang-tidy/checkers/performance/prefer-single-char-overloads.cpp Removed: ################################################################################ diff --git a/clang-tools-extra/clang-tidy/performance/PreferSingleCharOverloadsCheck.cpp b/clang-tools-extra/clang-tidy/performance/PreferSingleCharOverloadsCheck.cpp index d5d1784c0a0b7..4f62bd2be7d83 100644 --- a/clang-tools-extra/clang-tidy/performance/PreferSingleCharOverloadsCheck.cpp +++ b/clang-tools-extra/clang-tidy/performance/PreferSingleCharOverloadsCheck.cpp @@ -11,6 +11,7 @@ #include "../utils/OptionsUtils.h" #include "clang/ASTMatchers/ASTMatchFinder.h" #include "llvm/Support/raw_ostream.h" +#include <algorithm> #include <optional> using namespace clang::ast_matchers; @@ -101,11 +102,15 @@ 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 (std::none_of(Literal->tokloc_begin(), Literal->tokloc_end(), + [](SourceLocation Loc) { return Loc.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 94e0f279d1c6c..8b32c22542aeb 100644 --- a/clang-tools-extra/docs/ReleaseNotes.md +++ b/clang-tools-extra/docs/ReleaseNotes.md @@ -295,6 +295,11 @@ infrastructure are described first, followed by tool-specific sections. {option}`ForRangeLoopClasses` to configure container classes that can be used as sources in range-based `for` loops. +- 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..58f28f8ff9ecf 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,26 @@ 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; +} + +#define SEP "_" +// CHECK-FIXES: #define SEP "_" + +void ConcatenatedMacro() { + std::string s; + s += "" SEP ""; + // CHECK-MESSAGES: [[@LINE-1]]:8: warning: 'operator+=' called with a + // CHECK-FIXES: s += "" SEP ""; +} + void SubstitutedTemplateType() { Wrapper<std::string>().value.find("a"); // CHECK-MESSAGES: [[@LINE-1]]:37: warning: 'find' called with a string literal _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
