aboutsummaryrefslogtreecommitdiff
path: root/clang-tools-extra/clang-tidy/readability/RedundantStringInitCheck.cpp
diff options
context:
space:
mode:
authorEtienne Bergeron <etienneb@google.com>2016-03-22 17:39:36 +0000
committerEtienne Bergeron <etienneb@google.com>2016-03-22 17:39:36 +0000
commit1329b986d2f25e838d4b27b1271da92b6578d5ca (patch)
treed0ded96ca81dcf5eb42466e832cf3d7ffe4fbe16 /clang-tools-extra/clang-tidy/readability/RedundantStringInitCheck.cpp
parent909e600abd1e8519352c1b5eabb1a962b911697c (diff)
downloadllvm-1329b986d2f25e838d4b27b1271da92b6578d5ca.zip
llvm-1329b986d2f25e838d4b27b1271da92b6578d5ca.tar.gz
llvm-1329b986d2f25e838d4b27b1271da92b6578d5ca.tar.bz2
[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 llvm-svn: 264069
Diffstat (limited to 'clang-tools-extra/clang-tidy/readability/RedundantStringInitCheck.cpp')
-rw-r--r--clang-tools-extra/clang-tidy/readability/RedundantStringInitCheck.cpp47
1 files changed, 32 insertions, 15 deletions
diff --git a/clang-tools-extra/clang-tidy/readability/RedundantStringInitCheck.cpp b/clang-tools-extra/clang-tidy/readability/RedundantStringInitCheck.cpp
index ad6c2cd..d49c55e 100644
--- a/clang-tools-extra/clang-tidy/readability/RedundantStringInitCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/RedundantStringInitCheck.cpp
@@ -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()));
+ // 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)))));
- // string foo = "";
- // OR
- // string bar("");
+ // 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);
}