https://github.com/zeyi2 updated 
https://github.com/llvm/llvm-project/pull/185559

>From cb8e9fdb2c62fc3dfa471ca6cf3392d259c9cb4d Mon Sep 17 00:00:00 2001
From: mtx <[email protected]>
Date: Sun, 8 Mar 2026 17:50:48 +0800
Subject: [PATCH 1/4] [clang-tidy] Fix false negatives in
 performance-faster-string-find with libstdc++

---
 .../performance/FasterStringFindCheck.cpp     | 15 ++---------
 .../performance/FasterStringFindCheck.h       |  3 +++
 clang-tools-extra/docs/ReleaseNotes.rst       |  9 ++++---
 .../performance/faster-string-find.cpp        | 26 ++++++++++++++++++-
 4 files changed, 36 insertions(+), 17 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/performance/FasterStringFindCheck.cpp 
b/clang-tools-extra/clang-tidy/performance/FasterStringFindCheck.cpp
index 52a4d70e15265..8a96d41944748 100644
--- a/clang-tools-extra/clang-tidy/performance/FasterStringFindCheck.cpp
+++ b/clang-tools-extra/clang-tidy/performance/FasterStringFindCheck.cpp
@@ -42,16 +42,6 @@ makeCharacterLiteral(const StringLiteral *Literal) {
   return Result;
 }
 
-namespace {
-
-AST_MATCHER_FUNCTION(ast_matchers::internal::Matcher<Expr>,
-                     hasSubstitutedType) {
-  return hasType(qualType(anyOf(substTemplateTypeParmType(),
-                                hasDescendant(substTemplateTypeParmType()))));
-}
-
-} // namespace
-
 FasterStringFindCheck::FasterStringFindCheck(StringRef Name,
                                              ClangTidyContext *Context)
     : ClangTidyCheck(Name, Context),
@@ -77,9 +67,8 @@ void FasterStringFindCheck::registerMatchers(MatchFinder 
*Finder) {
           callee(functionDecl(InterestingStringFunction).bind("func")),
           anyOf(argumentCountIs(1), argumentCountIs(2)),
           hasArgument(0, SingleChar),
-          
on(expr(hasType(hasUnqualifiedDesugaredType(recordType(hasDeclaration(
-                      recordDecl(hasAnyName(StringLikeClasses)))))),
-                  unless(hasSubstitutedType())))),
+          on(expr(hasType(hasUnqualifiedDesugaredType(recordType(
+              hasDeclaration(recordDecl(hasAnyName(StringLikeClasses))))))))),
       this);
 }
 
diff --git a/clang-tools-extra/clang-tidy/performance/FasterStringFindCheck.h 
b/clang-tools-extra/clang-tidy/performance/FasterStringFindCheck.h
index 74067c1f5792d..f5d36d805498e 100644
--- a/clang-tools-extra/clang-tidy/performance/FasterStringFindCheck.h
+++ b/clang-tools-extra/clang-tidy/performance/FasterStringFindCheck.h
@@ -28,6 +28,9 @@ class FasterStringFindCheck : public ClangTidyCheck {
   bool isLanguageVersionSupported(const LangOptions &LangOpts) const override {
     return LangOpts.CPlusPlus;
   }
+  std::optional<TraversalKind> getCheckTraversalKind() const override {
+    return TK_IgnoreUnlessSpelledInSource;
+  }
   void registerMatchers(ast_matchers::MatchFinder *Finder) override;
   void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
   void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst 
b/clang-tools-extra/docs/ReleaseNotes.rst
index cf8dd0dba9f12..8f4bb6e247ca8 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -231,9 +231,12 @@ Changes in existing checks
   - Improved the ignore list to correctly handle ``typedef`` and  ``enum``.
 
 - Improved :doc:`performance-faster-string-find
-  <clang-tidy/checks/performance/faster-string-find>` check to
-  analyze calls to the ``starts_with``, ``ends_with``, and ``contains``
-  string member functions.
+  <clang-tidy/checks/performance/faster-string-find>` check:
+
+  - Analyze calls to the ``starts_with``, ``ends_with``, and ``contains``
+    string member functions.
+
+  - Fixes false negatives when using ``std::set`` from ``libstdc++``.
 
 - Improved :doc:`performance-inefficient-vector-operation
   <clang-tidy/checks/performance/inefficient-vector-operation>` check by
diff --git 
a/clang-tools-extra/test/clang-tidy/checkers/performance/faster-string-find.cpp 
b/clang-tools-extra/test/clang-tidy/checkers/performance/faster-string-find.cpp
index 83824c62494e7..55f52643d89ab 100644
--- 
a/clang-tools-extra/test/clang-tidy/checkers/performance/faster-string-find.cpp
+++ 
b/clang-tools-extra/test/clang-tidy/checkers/performance/faster-string-find.cpp
@@ -38,6 +38,16 @@ struct basic_string_view {
 
 typedef basic_string_view<char> string_view;
 typedef basic_string_view<wchar_t> wstring_view;
+
+template <typename T> struct set {
+  struct iterator {
+    const T& operator*() const;
+    iterator& operator++();
+    bool operator!=(const iterator&) const;
+  };
+  iterator begin() const;
+  iterator end() const;
+};
 }  // namespace std
 
 namespace llvm {
@@ -143,9 +153,14 @@ int FindTemplateDependant(T value) {
 }
 template <typename T>
 int FindTemplateNotDependant(T pos) {
+  // Ignored since the type of `pos` is dependent, the call cannot be 
completely resolved without instantiating the template.
   return std::string().find("A", pos);
+}
+template <typename T>
+int FindTemplateNotDependant2() {
+  return std::string().find("A");
   // CHECK-MESSAGES: [[@LINE-1]]:29: warning: 'find' called with a string 
literal
-  // CHECK-FIXES: return std::string().find('A', pos);
+  // CHECK-FIXES: return std::string().find('A');
 }
 
 int FindStr() {
@@ -160,3 +175,12 @@ int Macros() {
   // CHECK-MESSAGES: [[@LINE-1]]:10: warning: 'find' called with a string 
literal
   // CHECK-MESSAGES: [[@LINE-2]]:37: warning: 'find' called with a string 
literal
 }
+
+void IteratorInLibStdCXX() {
+  std::set<std::string> s;
+  for (const auto &str : s) {
+    str.find("a");
+    // CHECK-MESSAGES: [[@LINE-1]]:14: warning: 'find' called with a string 
literal
+    // CHECK-FIXES: str.find('a');
+  }
+}

>From 2dd086b744d6bf89aa8996a16ec49e5a26f1c0ec Mon Sep 17 00:00:00 2001
From: mtx <[email protected]>
Date: Tue, 10 Mar 2026 10:51:11 +0800
Subject: [PATCH 2/4] ~

---
 .../test/clang-tidy/checkers/performance/faster-string-find.cpp  | 1 +
 1 file changed, 1 insertion(+)

diff --git 
a/clang-tools-extra/test/clang-tidy/checkers/performance/faster-string-find.cpp 
b/clang-tools-extra/test/clang-tidy/checkers/performance/faster-string-find.cpp
index bcc500fc047d3..f358042d426a0 100644
--- 
a/clang-tools-extra/test/clang-tidy/checkers/performance/faster-string-find.cpp
+++ 
b/clang-tools-extra/test/clang-tidy/checkers/performance/faster-string-find.cpp
@@ -5,6 +5,7 @@
 // RUN:                '::llvm::StringRef;'}}"
 #include <string>
 
+// Mock for libstdc++
 namespace std {
 template <typename T> struct set {
   struct iterator {

>From e4583e0d629a0cfb7df65896903994535c319115 Mon Sep 17 00:00:00 2001
From: mtx <[email protected]>
Date: Tue, 10 Mar 2026 11:03:05 +0800
Subject: [PATCH 3/4] fixup fixup fixup

---
 .../clang-tidy/performance/FasterStringFindCheck.cpp         | 5 ++---
 .../clang-tidy/checkers/performance/faster-string-find.cpp   | 3 +--
 2 files changed, 3 insertions(+), 5 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/performance/FasterStringFindCheck.cpp 
b/clang-tools-extra/clang-tidy/performance/FasterStringFindCheck.cpp
index 96ad60bb2fdd4..1d9325166e341 100644
--- a/clang-tools-extra/clang-tidy/performance/FasterStringFindCheck.cpp
+++ b/clang-tools-extra/clang-tidy/performance/FasterStringFindCheck.cpp
@@ -58,9 +58,8 @@ void FasterStringFindCheck::registerMatchers(MatchFinder 
*Finder) {
   const auto SingleChar =
       ignoringParenCasts(stringLiteral(hasSize(1)).bind("literal"));
 
-  const auto StringExpr =
-      expr(hasType(hasUnqualifiedDesugaredType(recordType(
-               hasDeclaration(recordDecl(hasAnyName(StringLikeClasses)))))));
+  const auto StringExpr = expr(hasType(hasUnqualifiedDesugaredType(
+      recordType(hasDeclaration(recordDecl(hasAnyName(StringLikeClasses)))))));
 
   const auto InterestingStringFunction = hasAnyName(
       "find", "rfind", "find_first_of", "find_first_not_of", "find_last_of",
diff --git 
a/clang-tools-extra/test/clang-tidy/checkers/performance/faster-string-find.cpp 
b/clang-tools-extra/test/clang-tidy/checkers/performance/faster-string-find.cpp
index f358042d426a0..dbb4fb8c1b0ad 100644
--- 
a/clang-tools-extra/test/clang-tidy/checkers/performance/faster-string-find.cpp
+++ 
b/clang-tools-extra/test/clang-tidy/checkers/performance/faster-string-find.cpp
@@ -5,7 +5,6 @@
 // RUN:                '::llvm::StringRef;'}}"
 #include <string>
 
-// Mock for libstdc++
 namespace std {
 template <typename T> struct set {
   struct iterator {
@@ -139,7 +138,7 @@ template <typename T>
 int FindTemplateNotDependant2() {
   return std::string().find("A");
   // CHECK-MESSAGES: [[@LINE-1]]:29: warning: 'find' called with a string 
literal
-  // CHECK-FIXES: return std::string().find('A');
+  // CHECK-FIXES:   return std::string().find('A');
 }
 
 int FindStr() {

>From f909b404d324bb4c020743ec91da812d5707ecb3 Mon Sep 17 00:00:00 2001
From: mtx <[email protected]>
Date: Tue, 10 Mar 2026 14:11:08 +0800
Subject: [PATCH 4/4] try again

---
 .../performance/faster-string-find.cpp        | 33 +++++++------------
 1 file changed, 11 insertions(+), 22 deletions(-)

diff --git 
a/clang-tools-extra/test/clang-tidy/checkers/performance/faster-string-find.cpp 
b/clang-tools-extra/test/clang-tidy/checkers/performance/faster-string-find.cpp
index dbb4fb8c1b0ad..63b229ccbb8e6 100644
--- 
a/clang-tools-extra/test/clang-tidy/checkers/performance/faster-string-find.cpp
+++ 
b/clang-tools-extra/test/clang-tidy/checkers/performance/faster-string-find.cpp
@@ -1,22 +1,10 @@
-// RUN: %check_clang_tidy %s performance-faster-string-find %t
+// RUN: %check_clang_tidy %s performance-faster-string-find %t -- -- 
-fno-delayed-template-parsing
 // RUN: %check_clang_tidy -check-suffix=CUSTOM %s 
performance-faster-string-find %t -- \
 // RUN:   -config="{CheckOptions: \
 // RUN:             {performance-faster-string-find.StringLikeClasses: \
-// RUN:                '::llvm::StringRef;'}}"
+// RUN:                '::llvm::StringRef;'}}" -- -fno-delayed-template-parsing
 #include <string>
 
-namespace std {
-template <typename T> struct set {
-  struct iterator {
-    const T& operator*() const;
-    iterator& operator++();
-    bool operator!=(const iterator&) const;
-  };
-  iterator begin() const;
-  iterator end() const;
-};
-}  // namespace std
-
 namespace llvm {
 struct StringRef {
   int find(const char *) const;
@@ -27,6 +15,10 @@ struct NotStringRef {
   int find(const char *);
 };
 
+template <typename T> struct Wrapper {
+  T value;
+};
+
 void StringFind() {
   std::string Str;
 
@@ -138,7 +130,7 @@ template <typename T>
 int FindTemplateNotDependant2() {
   return std::string().find("A");
   // CHECK-MESSAGES: [[@LINE-1]]:29: warning: 'find' called with a string 
literal
-  // CHECK-FIXES:   return std::string().find('A');
+  // CHECK-FIXES: return std::string().find('A');
 }
 
 int FindStr() {
@@ -154,11 +146,8 @@ int Macros() {
   // CHECK-MESSAGES: [[@LINE-2]]:37: warning: 'find' called with a string 
literal
 }
 
-void IteratorInLibStdCXX() {
-  std::set<std::string> s;
-  for (const auto &str : s) {
-    str.find("a");
-    // CHECK-MESSAGES: [[@LINE-1]]:14: warning: 'find' called with a string 
literal
-    // CHECK-FIXES: str.find('a');
-  }
+void SubstitutedTemplateType() {
+  Wrapper<std::string>().value.find("a");
+  // CHECK-MESSAGES: [[@LINE-1]]:37: warning: 'find' called with a string 
literal
+  // CHECK-FIXES: Wrapper<std::string>().value.find('a');
 }

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to