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

None

>From cb8e9fdb2c62fc3dfa471ca6cf3392d259c9cb4d Mon Sep 17 00:00:00 2001
From: mtx <[email protected]>
Date: Sun, 8 Mar 2026 17:50:48 +0800
Subject: [PATCH] [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');
+  }
+}

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

Reply via email to