Index: clang-tidy/readability/RedundantStringCStrCheck.cpp =================================================================== --- clang-tidy/readability/RedundantStringCStrCheck.cpp +++ clang-tidy/readability/RedundantStringCStrCheck.cpp @@ -66,11 +66,11 @@ } const char StringConstructor[] = - "::std::basic_string, std::allocator >" + "::std::basic_string<.*, std::char_traits<.*>, std::allocator<.*> >" "::basic_string"; const char StringCStrMethod[] = - "::std::basic_string, std::allocator >" + "::std::basic_string<.*, std::char_traits<.*>, std::allocator<.*> >" "::c_str"; } // end namespace @@ -89,18 +89,18 @@ const auto StringConstructorExpr = expr(anyOf( cxxConstructExpr( argumentCountIs(1), - hasDeclaration(cxxMethodDecl(hasName(StringConstructor)))), + hasDeclaration(cxxMethodDecl(matchesName(StringConstructor)))), cxxConstructExpr( argumentCountIs(2), - hasDeclaration(cxxMethodDecl(hasName(StringConstructor))), + hasDeclaration(cxxMethodDecl(matchesName(StringConstructor))), // If present, the second argument is the alloc object which must not // be present explicitly. hasArgument(1, cxxDefaultArgExpr())))); // Match a call to the string 'c_str()' method. - const auto StringCStrCallExpr = cxxMemberCallExpr( - callee(memberExpr().bind("member")), - callee(cxxMethodDecl(hasName(StringCStrMethod))), + const auto StringCStrCallExpr = + cxxMemberCallExpr(callee(memberExpr().bind("member")), + callee(cxxMethodDecl(matchesName(StringCStrMethod))), on(expr().bind("arg"))).bind("call"); Finder->addMatcher( Index: test/clang-tidy/readability-redundant-string-cstr.cpp =================================================================== --- test/clang-tidy/readability-redundant-string-cstr.cpp +++ test/clang-tidy/readability-redundant-string-cstr.cpp @@ -12,7 +12,11 @@ const C *c_str() const; }; typedef basic_string, std::allocator> string; +typedef basic_string, std::allocator> wstring; +typedef basic_string, std::allocator> u16string; +typedef basic_string, std::allocator> u32string; } + namespace llvm { struct StringRef { StringRef(const char *p); @@ -20,6 +24,8 @@ }; } +// Tests for std::string. + void f1(const std::string &s) { f1(s.c_str()); // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: redundant call to `c_str()` [readability-redundant-string-cstr] @@ -39,3 +45,27 @@ // CHECK-FIXES: {{^ }}std::string s;{{$}} // CHECK-FIXES-NEXT: {{^ }}f3(s);{{$}} } + +// Tests for std::wstring. + +void g1(const std::wstring &s) { + g1(s.c_str()); + // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: redundant call to `c_str()` [readability-redundant-string-cstr] + // CHECK-FIXES: {{^ }}f1(s);{{$}} +} + +// Tests for std::u16string. + +void h1(const std::u16string &s) { + h1(s.c_str()); + // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: redundant call to `c_str()` [readability-redundant-string-cstr] + // CHECK-FIXES: {{^ }}f1(s);{{$}} +} + +// Tests for std::u32string. + +void k1(const std::u32string &s) { + k1(s.c_str()); + // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: redundant call to `c_str()` [readability-redundant-string-cstr] + // CHECK-FIXES: {{^ }}f1(s);{{$}} +}