[clang-tools-extra] r264069 - [clang-tidy] Fix redundant-string-init check with msvc 14 headers.
Etienne Bergeron via cfe-commits
cfe-commits at lists.llvm.org
Tue Mar 22 10:39:37 PDT 2016
Author: etienneb
Date: Tue Mar 22 12:39:36 2016
New Revision: 264069
URL: http://llvm.org/viewvc/llvm-project?rev=264069&view=rev
Log:
[clang-tidy] Fix redundant-string-init check with msvc 14 headers.
Summary:
The string constructors are not defined using optional parameters and are not recognized by the redundant-string-init checker.
The following patch fixes the redundant-string-init checker for the Visual Studio 14 headers file.
The matcher now accept both variant (with 1 and 2 parameters).
Also added new unittests.
Similar issue than: [[ http://reviews.llvm.org/D18285 | review ]]
In the xstring.h header, the constructors are defined this way:
```
basic_string(const _Myt& _Right) [...]
basic_string(const _Myt& _Right, const _Alloc& _Al) [...]
```
Reviewers: alexfh, hokein
Subscribers: cfe-commits
Differential Revision: http://reviews.llvm.org/D18293
Added:
clang-tools-extra/trunk/test/clang-tidy/readability-redundant-string-init-msvc.cpp
Modified:
clang-tools-extra/trunk/clang-tidy/readability/RedundantStringInitCheck.cpp
clang-tools-extra/trunk/test/clang-tidy/readability-redundant-string-init.cpp
Modified: clang-tools-extra/trunk/clang-tidy/readability/RedundantStringInitCheck.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/readability/RedundantStringInitCheck.cpp?rev=264069&r1=264068&r2=264069&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/readability/RedundantStringInitCheck.cpp (original)
+++ clang-tools-extra/trunk/clang-tidy/readability/RedundantStringInitCheck.cpp Tue Mar 22 12:39:36 2016
@@ -20,31 +20,48 @@ namespace {
AST_MATCHER(StringLiteral, lengthIsZero) { return Node.getLength() == 0; }
+AST_MATCHER_P(Expr, ignoringImplicit,
+ ast_matchers::internal::Matcher<Expr>, InnerMatcher) {
+ return InnerMatcher.matches(*Node.IgnoreImplicit(), Finder, Builder);
+}
+
} // namespace
void RedundantStringInitCheck::registerMatchers(MatchFinder *Finder) {
if (!getLangOpts().CPlusPlus)
return;
- const auto StringCtorExpr = cxxConstructExpr(
- hasDeclaration(cxxMethodDecl(hasName("basic_string"))),
- argumentCountIs(2),
- hasArgument(0, ignoringParenImpCasts(stringLiteral(lengthIsZero()))),
- hasArgument(1, cxxDefaultArgExpr()));
-
- // string foo = "";
- // OR
- // string bar("");
+ // Match string constructor.
+ const auto StringConstructorExpr = expr(anyOf(
+ cxxConstructExpr(argumentCountIs(1),
+ hasDeclaration(cxxMethodDecl(hasName("basic_string")))),
+ // If present, the second argument is the alloc object which must not
+ // be present explicitly.
+ cxxConstructExpr(argumentCountIs(2),
+ hasDeclaration(cxxMethodDecl(hasName("basic_string"))),
+ hasArgument(1, cxxDefaultArgExpr()))));
+
+ // Match a string constructor expression with an empty string literal.
+ const auto EmptyStringCtorExpr =
+ cxxConstructExpr(StringConstructorExpr,
+ hasArgument(0, ignoringParenImpCasts(
+ stringLiteral(lengthIsZero()))));
+
+ const auto EmptyStringCtorExprWithTemporaries =
+ expr(ignoringImplicit(
+ cxxConstructExpr(StringConstructorExpr,
+ hasArgument(0, ignoringImplicit(EmptyStringCtorExpr)))));
+
+ // Match a variable declaration with an empty string literal as initializer.
+ // Examples:
+ // string foo = "";
+ // string bar("");
Finder->addMatcher(
namedDecl(varDecl(hasType(cxxRecordDecl(hasName("basic_string"))),
hasInitializer(
- expr(anyOf(StringCtorExpr,
- exprWithCleanups(has(expr(anyOf(
- StringCtorExpr,
- cxxConstructExpr(hasArgument(
- 0, cxxBindTemporaryExpr(has(
- StringCtorExpr))))))))))
- .bind("expr"))))
+ expr(anyOf(EmptyStringCtorExpr,
+ EmptyStringCtorExprWithTemporaries))
+ .bind("expr"))))
.bind("decl"),
this);
}
Added: clang-tools-extra/trunk/test/clang-tidy/readability-redundant-string-init-msvc.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/readability-redundant-string-init-msvc.cpp?rev=264069&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/readability-redundant-string-init-msvc.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/readability-redundant-string-init-msvc.cpp Tue Mar 22 12:39:36 2016
@@ -0,0 +1,122 @@
+// RUN: %check_clang_tidy %s readability-redundant-string-init %t
+
+namespace std {
+template <typename T>
+class allocator {};
+template <typename T>
+class char_traits {};
+template <typename C, typename T = std::char_traits<C>, typename A = std::allocator<C>>
+struct basic_string {
+ basic_string();
+ basic_string(const basic_string&);
+ // MSVC headers define two constructors instead of using optional arguments.
+ basic_string(const C *);
+ basic_string(const C *, const A &);
+ ~basic_string();
+};
+typedef basic_string<char> string;
+typedef basic_string<wchar_t> wstring;
+}
+
+void f() {
+ std::string a = "";
+ // CHECK-MESSAGES: [[@LINE-1]]:15: warning: redundant string initialization [readability-redundant-string-init]
+ // CHECK-FIXES: std::string a;
+ std::string b("");
+ // CHECK-MESSAGES: [[@LINE-1]]:15: warning: redundant string initialization
+ // CHECK-FIXES: std::string b;
+ std::string c = R"()";
+ // CHECK-MESSAGES: [[@LINE-1]]:15: warning: redundant string initialization
+ // CHECK-FIXES: std::string c;
+ std::string d(R"()");
+ // CHECK-MESSAGES: [[@LINE-1]]:15: warning: redundant string initialization
+ // CHECK-FIXES: std::string d;
+
+ std::string u = "u";
+ std::string w("w");
+ std::string x = R"(x)";
+ std::string y(R"(y)");
+ std::string z;
+}
+
+void g() {
+ std::wstring a = L"";
+ // CHECK-MESSAGES: [[@LINE-1]]:16: warning: redundant string initialization
+ // CHECK-FIXES: std::wstring a;
+ std::wstring b(L"");
+ // CHECK-MESSAGES: [[@LINE-1]]:16: warning: redundant string initialization
+ // CHECK-FIXES: std::wstring b;
+ std::wstring c = LR"()";
+ // CHECK-MESSAGES: [[@LINE-1]]:16: warning: redundant string initialization
+ // CHECK-FIXES: std::wstring c;
+ std::wstring d(LR"()");
+ // CHECK-MESSAGES: [[@LINE-1]]:16: warning: redundant string initialization
+ // CHECK-FIXES: std::wstring d;
+
+ std::wstring u = L"u";
+ std::wstring w(L"w");
+ std::wstring x = LR"(x)";
+ std::wstring y(LR"(y)");
+ std::wstring z;
+}
+// RUN: %check_clang_tidy %s readability-redundant-string-init %t
+
+namespace std {
+template <typename T>
+class allocator {};
+template <typename T>
+class char_traits {};
+template <typename C, typename T = std::char_traits<C>, typename A = std::allocator<C>>
+struct basic_string {
+ basic_string();
+ basic_string(const basic_string&);
+ // MSVC headers define two constructors instead of using optional arguments.
+ basic_string(const C *);
+ basic_string(const C *, const A &);
+ ~basic_string();
+};
+typedef basic_string<char> string;
+typedef basic_string<wchar_t> wstring;
+}
+
+void f() {
+ std::string a = "";
+ // CHECK-MESSAGES: [[@LINE-1]]:15: warning: redundant string initialization [readability-redundant-string-init]
+ // CHECK-FIXES: std::string a;
+ std::string b("");
+ // CHECK-MESSAGES: [[@LINE-1]]:15: warning: redundant string initialization
+ // CHECK-FIXES: std::string b;
+ std::string c = R"()";
+ // CHECK-MESSAGES: [[@LINE-1]]:15: warning: redundant string initialization
+ // CHECK-FIXES: std::string c;
+ std::string d(R"()");
+ // CHECK-MESSAGES: [[@LINE-1]]:15: warning: redundant string initialization
+ // CHECK-FIXES: std::string d;
+
+ std::string u = "u";
+ std::string w("w");
+ std::string x = R"(x)";
+ std::string y(R"(y)");
+ std::string z;
+}
+
+void g() {
+ std::wstring a = L"";
+ // CHECK-MESSAGES: [[@LINE-1]]:16: warning: redundant string initialization
+ // CHECK-FIXES: std::wstring a;
+ std::wstring b(L"");
+ // CHECK-MESSAGES: [[@LINE-1]]:16: warning: redundant string initialization
+ // CHECK-FIXES: std::wstring b;
+ std::wstring c = LR"()";
+ // CHECK-MESSAGES: [[@LINE-1]]:16: warning: redundant string initialization
+ // CHECK-FIXES: std::wstring c;
+ std::wstring d(LR"()");
+ // CHECK-MESSAGES: [[@LINE-1]]:16: warning: redundant string initialization
+ // CHECK-FIXES: std::wstring d;
+
+ std::wstring u = L"u";
+ std::wstring w(L"w");
+ std::wstring x = LR"(x)";
+ std::wstring y(LR"(y)");
+ std::wstring z;
+}
Modified: clang-tools-extra/trunk/test/clang-tidy/readability-redundant-string-init.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/readability-redundant-string-init.cpp?rev=264069&r1=264068&r2=264069&view=diff
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/readability-redundant-string-init.cpp (original)
+++ clang-tools-extra/trunk/test/clang-tidy/readability-redundant-string-init.cpp Tue Mar 22 12:39:36 2016
@@ -84,3 +84,50 @@ void h() {
// CHECK-MESSAGES: [[@LINE-1]]:3: warning: redundant string initialization
// CHECK-FIXES: N
}
+
+typedef std::string MyString;
+#define STRING MyString
+#define DECL_STRING(name, val) STRING name = val
+
+void i() {
+ MyString a = "";
+ // CHECK-MESSAGES: [[@LINE-1]]:12: warning: redundant string initialization
+ // CHECK-FIXES: MyString a;
+ STRING b = "";
+ // CHECK-MESSAGES: [[@LINE-1]]:10: warning: redundant string initialization
+ // CHECK-FIXES: STRING b;
+ MyString c = "" "" "";
+ // CHECK-MESSAGES: [[@LINE-1]]:12: warning: redundant string initialization
+ // CHECK-FIXES: MyString c;
+ STRING d = "" "" "";
+ // CHECK-MESSAGES: [[@LINE-1]]:10: warning: redundant string initialization
+ // CHECK-FIXES: STRING d;
+ DECL_STRING(e, "");
+ // CHECK-MESSAGES: [[@LINE-1]]:15: warning: redundant string initialization
+
+ MyString f = "u";
+ STRING g = "u";
+ DECL_STRING(h, "u");
+}
+
+#define EMPTY_STR ""
+void j() {
+ std::string a(EMPTY_STR);
+ // CHECK-MESSAGES: [[@LINE-1]]:15: warning: redundant string initialization
+ // CHECK-FIXES: std::string a;
+ std::string b = (EMPTY_STR);
+ // CHECK-MESSAGES: [[@LINE-1]]:15: warning: redundant string initialization
+ // CHECK-FIXES: std::string b;
+
+ std::string c(EMPTY_STR "u" EMPTY_STR);
+}
+
+void k() {
+ std::string a = "", b = "", c = "";
+ // CHECK-MESSAGES: [[@LINE-1]]:15: warning: redundant string initialization
+ // CHECK-MESSAGES: [[@LINE-2]]:23: warning: redundant string initialization
+ // CHECK-MESSAGES: [[@LINE-3]]:31: warning: redundant string initialization
+ // CHECK-FIXES: std::string a, b, c;
+
+ std::string d = "u", e = "u", f = "u";
+}
More information about the cfe-commits
mailing list