diff options
author | Etienne Bergeron <etienneb@google.com> | 2016-03-22 17:39:36 +0000 |
---|---|---|
committer | Etienne Bergeron <etienneb@google.com> | 2016-03-22 17:39:36 +0000 |
commit | 1329b986d2f25e838d4b27b1271da92b6578d5ca (patch) | |
tree | d0ded96ca81dcf5eb42466e832cf3d7ffe4fbe16 /clang-tools-extra/clang-tidy/readability/RedundantStringInitCheck.cpp | |
parent | 909e600abd1e8519352c1b5eabb1a962b911697c (diff) | |
download | llvm-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.cpp | 47 |
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); } |