diff --git a/clang-tools-extra/clang-tidy/abseil/StringFindStrContainsCheck.cpp b/clang-tools-extra/clang-tidy/abseil/StringFindStrContainsCheck.cpp --- 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::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 @@ 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 --- 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 @@ // 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))