etienneb created this revision. etienneb added a reviewer: alexfh. etienneb added a subscriber: cfe-commits.
The current checker is able to recognize std::string but do not recognize other string variants. This path is adding the support for any string define with basic_string without consiring the the char type. The most common variant is: std::wstring based on wchar_t. There are also other string variants added to the standard: u16string, u32string, etc... http://reviews.llvm.org/D18412 Files: clang-tidy/readability/RedundantStringCStrCheck.cpp test/clang-tidy/readability-redundant-string-cstr.cpp 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,14 +12,20 @@ const C *c_str() const; }; typedef basic_string<char, std::char_traits<char>, std::allocator<char>> string; +typedef basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t>> wstring; +typedef basic_string<char16_t, std::char_traits<char16_t>, std::allocator<char16_t>> u16string; +typedef basic_string<char32_t, std::char_traits<char32_t>, std::allocator<char32_t>> u32string; } + namespace llvm { struct StringRef { StringRef(const char *p); StringRef(const std::string &); }; } +// 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);{{$}} +} 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<char, std::char_traits<char>, std::allocator<char> >" + "::std::basic_string<.*, std::char_traits<.*>, std::allocator<.*> >" "::basic_string"; const char StringCStrMethod[] = - "::std::basic_string<char, std::char_traits<char>, std::allocator<char> >" + "::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,14 +12,20 @@ const C *c_str() const; }; typedef basic_string<char, std::char_traits<char>, std::allocator<char>> string; +typedef basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t>> wstring; +typedef basic_string<char16_t, std::char_traits<char16_t>, std::allocator<char16_t>> u16string; +typedef basic_string<char32_t, std::char_traits<char32_t>, std::allocator<char32_t>> u32string; } + namespace llvm { struct StringRef { StringRef(const char *p); StringRef(const std::string &); }; } +// 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);{{$}} +} 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<char, std::char_traits<char>, std::allocator<char> >" + "::std::basic_string<.*, std::char_traits<.*>, std::allocator<.*> >" "::basic_string"; const char StringCStrMethod[] = - "::std::basic_string<char, std::char_traits<char>, std::allocator<char> >" + "::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(
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits