summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEtienne Bergeron <etienneb@google.com>2016-03-24 19:42:36 +0000
committerEtienne Bergeron <etienneb@google.com>2016-03-24 19:42:36 +0000
commitcb7ce98486c3f6b6025130e95b71acd8c04d7b4d (patch)
tree7a83a96d6e78f7da24968de441464a972e952bc9
parent181fdbd174861a9001ec481a500221ea0f6a6b40 (diff)
downloadbcm5719-llvm-cb7ce98486c3f6b6025130e95b71acd8c04d7b4d.tar.gz
bcm5719-llvm-cb7ce98486c3f6b6025130e95b71acd8c04d7b4d.zip
[clang-tidy] Add support for different char-types for the readability-redundant-string-cstr checker.
Summary: The current checker is able to recognize std::string but does not recognize other string variants. This patch is adding the support for any string defined with basic_string without considering the the underlying 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... Reviewers: alexfh Subscribers: mamai, dblaikie, cfe-commits Differential Revision: http://reviews.llvm.org/D18412 llvm-svn: 264325
-rw-r--r--clang-tools-extra/clang-tidy/readability/RedundantStringCStrCheck.cpp28
-rw-r--r--clang-tools-extra/test/clang-tidy/readability-redundant-string-cstr.cpp50
2 files changed, 64 insertions, 14 deletions
diff --git a/clang-tools-extra/clang-tidy/readability/RedundantStringCStrCheck.cpp b/clang-tools-extra/clang-tidy/readability/RedundantStringCStrCheck.cpp
index 64a7b61b51b..13a330b8ffa 100644
--- a/clang-tools-extra/clang-tidy/readability/RedundantStringCStrCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/RedundantStringCStrCheck.cpp
@@ -65,14 +65,6 @@ formatDereference(const ast_matchers::MatchFinder::MatchResult &Result,
return (llvm::Twine("*") + Text).str();
}
-const char StringConstructor[] =
- "::std::basic_string<char, std::char_traits<char>, std::allocator<char> >"
- "::basic_string";
-
-const char StringCStrMethod[] =
- "::std::basic_string<char, std::char_traits<char>, std::allocator<char> >"
- "::c_str";
-
} // end namespace
namespace tidy {
@@ -85,23 +77,31 @@ void RedundantStringCStrCheck::registerMatchers(
if (!getLangOpts().CPlusPlus)
return;
+ // Match expressions of type 'string' or 'string*'.
+ const auto StringDecl =
+ cxxRecordDecl(hasName("::std::basic_string"));
+ const auto StringExpr =
+ expr(anyOf(hasType(StringDecl),
+ hasType(qualType(pointsTo(StringDecl)))));
+
// Match string constructor.
const auto StringConstructorExpr = expr(anyOf(
cxxConstructExpr(
argumentCountIs(1),
- hasDeclaration(cxxMethodDecl(hasName(StringConstructor)))),
+ hasDeclaration(cxxMethodDecl(hasName("basic_string")))),
cxxConstructExpr(
argumentCountIs(2),
- hasDeclaration(cxxMethodDecl(hasName(StringConstructor))),
+ hasDeclaration(cxxMethodDecl(hasName("basic_string"))),
// 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))),
- on(expr().bind("arg"))).bind("call");
+ const auto StringCStrCallExpr =
+ cxxMemberCallExpr(on(StringExpr.bind("arg")),
+ callee(memberExpr().bind("member")),
+ callee(cxxMethodDecl(hasName("c_str"))))
+ .bind("call");
Finder->addMatcher(
cxxConstructExpr(StringConstructorExpr,
diff --git a/clang-tools-extra/test/clang-tidy/readability-redundant-string-cstr.cpp b/clang-tools-extra/test/clang-tidy/readability-redundant-string-cstr.cpp
index e6f6328dad5..2bac1c4d499 100644
--- a/clang-tools-extra/test/clang-tidy/readability-redundant-string-cstr.cpp
+++ b/clang-tools-extra/test/clang-tidy/readability-redundant-string-cstr.cpp
@@ -12,7 +12,11 @@ struct basic_string {
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);
@@ -20,6 +24,8 @@ struct StringRef {
};
}
+// 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,47 @@ void f3(const llvm::StringRef &r) {
// CHECK-FIXES: {{^ }}std::string s;{{$}}
// CHECK-FIXES-NEXT: {{^ }}f3(s);{{$}}
}
+void f4(const std::string &s) {
+ const std::string* ptr = &s;
+ f1(ptr->c_str());
+ // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: redundant call to `c_str()` [readability-redundant-string-cstr]
+ // CHECK-FIXES: {{^ }}f1(*ptr);{{$}}
+}
+
+// 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: {{^ }}g1(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: {{^ }}h1(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: {{^ }}k1(s);{{$}}
+}
+
+// Tests on similar classes that aren't good candidates for this checker.
+
+struct NotAString {
+ NotAString();
+ NotAString(const NotAString&);
+ const char *c_str() const;
+};
+
+void dummy(const char*) {}
+
+void invalid(const NotAString &s) {
+ dummy(s.c_str());
+}
OpenPOWER on IntegriCloud