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
