[clang-tools-extra] [clang-tidy] Fix false negatives in performance-faster-string-find with libstdc++ (PR #185559)
via cfe-commits
cfe-commits at lists.llvm.org
Mon Mar 9 19:37:38 PDT 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang-tidy
@llvm/pr-subscribers-clang-tools-extra
Author: mitchell (zeyi2)
<details>
<summary>Changes</summary>
---
Full diff: https://github.com/llvm/llvm-project/pull/185559.diff
4 Files Affected:
- (modified) clang-tools-extra/clang-tidy/performance/FasterStringFindCheck.cpp (+2-13)
- (modified) clang-tools-extra/clang-tidy/performance/FasterStringFindCheck.h (+3)
- (modified) clang-tools-extra/docs/ReleaseNotes.rst (+6-3)
- (modified) clang-tools-extra/test/clang-tidy/checkers/performance/faster-string-find.cpp (+25-1)
``````````diff
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');
+ }
+}
``````````
</details>
https://github.com/llvm/llvm-project/pull/185559
More information about the cfe-commits
mailing list