From 16622d535c021b566c1304b6388a6399e3333606 Mon Sep 17 00:00:00 2001 From: Chris Kennelly Date: Sun, 6 Dec 2020 11:26:31 -0500 Subject: [PATCH] [clang-tidy] Recognize single character needles for absl::StrContains. Commit fbdff6f3ae0b in the Abseil tree adds an overload for absl::StrContains to accept a single character needle for optimized lookups. Reviewed By: hokein Differential Revision: https://reviews.llvm.org/D92810 --- .../clang-tidy/abseil/StringFindStrContainsCheck.cpp | 8 ++++++-- .../clang-tidy/checkers/abseil-string-find-str-contains.cpp | 10 +++++++--- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/clang-tools-extra/clang-tidy/abseil/StringFindStrContainsCheck.cpp b/clang-tools-extra/clang-tidy/abseil/StringFindStrContainsCheck.cpp index cd890e4837e..977c1919cee 100644 --- a/clang-tools-extra/clang-tidy/abseil/StringFindStrContainsCheck.cpp +++ b/clang-tools-extra/clang-tidy/abseil/StringFindStrContainsCheck.cpp @@ -31,6 +31,8 @@ using ::clang::transformer::makeRule; using ::clang::transformer::node; using ::clang::transformer::RewriteRule; +AST_MATCHER(Type, isCharType) { return Node.isCharType(); } + static const char DefaultStringLikeClasses[] = "::std::basic_string;" "::std::basic_string_view;" "::absl::string_view"; @@ -58,13 +60,15 @@ MakeRule(const LangOptions &LangOpts, hasUnqualifiedDesugaredType(recordType(hasDeclaration(StringLikeClass))); auto CharStarType = hasUnqualifiedDesugaredType(pointerType(pointee(isAnyCharacter()))); + auto CharType = hasUnqualifiedDesugaredType(isCharType()); auto StringNpos = declRefExpr( to(varDecl(hasName("npos"), hasDeclContext(StringLikeClass)))); auto StringFind = cxxMemberCallExpr( callee(cxxMethodDecl( hasName("find"), - hasParameter(0, parmVarDecl(anyOf(hasType(StringType), - hasType(CharStarType)))))), + hasParameter( + 0, parmVarDecl(anyOf(hasType(StringType), hasType(CharStarType), + hasType(CharType)))))), on(hasType(StringType)), hasArgument(0, expr().bind("parameter_to_find")), anyOf(hasArgument(1, integerLiteral(equals(0))), hasArgument(1, cxxDefaultArgExpr())), diff --git a/clang-tools-extra/test/clang-tidy/checkers/abseil-string-find-str-contains.cpp b/clang-tools-extra/test/clang-tidy/checkers/abseil-string-find-str-contains.cpp index 9d4b03aa22f..81a3fc4d3b9 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/abseil-string-find-str-contains.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/abseil-string-find-str-contains.cpp @@ -226,17 +226,21 @@ void string_literal_and_char_ptr_tests() { // CHECK-FIXES: {{^[[:space:]]*}}!absl::StrContains(asv, cc);{{$}} } -// Confirms that it does *not* match when the parameter to find() is a char, -// because absl::StrContains is not implemented for char. -void no_char_param_tests() { +void char_param_tests() { std::string ss; ss.find('c') == std::string::npos; + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use !absl::StrContains instead of + // CHECK-FIXES: {{^[[:space:]]*}}!absl::StrContains(ss, 'c');{{$}} std::string_view ssv; ssv.find('c') == std::string_view::npos; + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use !absl::StrContains instead of + // CHECK-FIXES: {{^[[:space:]]*}}!absl::StrContains(ssv, 'c');{{$}} absl::string_view asv; asv.find('c') == absl::string_view::npos; + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use !absl::StrContains instead of + // CHECK-FIXES: {{^[[:space:]]*}}!absl::StrContains(asv, 'c');{{$}} } #define FOO(a, b, c, d) ((a).find(b) == std::string::npos ? (c) : (d)) -- 2.11.0