Index: clang-tools-extra/trunk/clang-tidy/abseil/StringFindStartswithCheck.cpp =================================================================== --- clang-tools-extra/trunk/clang-tidy/abseil/StringFindStartswithCheck.cpp +++ clang-tools-extra/trunk/clang-tidy/abseil/StringFindStartswithCheck.cpp @@ -36,10 +36,13 @@ auto ZeroLiteral = integerLiteral(equals(0)); auto StringClassMatcher = cxxRecordDecl(hasAnyName(SmallVector( StringLikeClasses.begin(), StringLikeClasses.end()))); + auto StringType = hasUnqualifiedDesugaredType( + recordType(hasDeclaration(StringClassMatcher))); auto StringFind = cxxMemberCallExpr( // .find()-call on a string... - callee(cxxMethodDecl(hasName("find"), ofClass(StringClassMatcher))), + callee(cxxMethodDecl(hasName("find"))), + on(hasType(StringType)), // ... with some search expression ... hasArgument(0, expr().bind("needle")), // ... and either "0" as second argument or the default argument (also 0). Index: clang-tools-extra/trunk/test/clang-tidy/abseil-string-find-startswith.cpp =================================================================== --- clang-tools-extra/trunk/test/clang-tidy/abseil-string-find-startswith.cpp +++ clang-tools-extra/trunk/test/clang-tidy/abseil-string-find-startswith.cpp @@ -1,4 +1,6 @@ -// RUN: %check_clang_tidy %s abseil-string-find-startswith %t +// RUN: %check_clang_tidy %s abseil-string-find-startswith %t -- \ +// RUN: -config="{CheckOptions: [{key: 'abseil-string-find-startswith.StringLikeClasses', value: '::std::basic_string;::basic_string'}]}" \ +// RUN: -- -std=c++11 namespace std { template class allocator {}; @@ -15,14 +17,23 @@ }; typedef basic_string string; typedef basic_string wstring; + +struct cxx_string { + int find(const char *s, int pos = 0); +}; } // namespace std +struct basic_string : public std::cxx_string { + basic_string(); +}; +typedef basic_string global_string; + std::string foo(std::string); std::string bar(); #define A_MACRO(x, y) ((x) == (y)) -void tests(std::string s) { +void tests(std::string s, global_string s2) { s.find("a") == 0; // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use absl::StartsWith instead of find() == 0 [abseil-string-find-startswith] // CHECK-FIXES: {{^[[:space:]]*}}absl::StartsWith(s, "a");{{$}} @@ -47,6 +58,10 @@ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use !absl::StartsWith // CHECK-FIXES: {{^[[:space:]]*}}!absl::StartsWith(s, "a");{{$}} + s2.find("a") == 0; + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use absl::StartsWith + // CHECK-FIXES: {{^[[:space:]]*}}absl::StartsWith(s2, "a");{{$}} + // expressions that don't trigger the check are here. A_MACRO(s.find("a"), 0); s.find("a", 1) == 0;