diff options
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 ad6c2cdd416..d49c55e8f1f 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); } |