diff options
Diffstat (limited to 'clang-tools-extra/clang-tidy/misc/StringConstructorCheck.cpp')
-rw-r--r-- | clang-tools-extra/clang-tidy/misc/StringConstructorCheck.cpp | 134 |
1 files changed, 0 insertions, 134 deletions
diff --git a/clang-tools-extra/clang-tidy/misc/StringConstructorCheck.cpp b/clang-tools-extra/clang-tidy/misc/StringConstructorCheck.cpp deleted file mode 100644 index 7ff488133f3..00000000000 --- a/clang-tools-extra/clang-tidy/misc/StringConstructorCheck.cpp +++ /dev/null @@ -1,134 +0,0 @@ -//===--- StringConstructorCheck.cpp - clang-tidy---------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "StringConstructorCheck.h" -#include "clang/AST/ASTContext.h" -#include "clang/ASTMatchers/ASTMatchFinder.h" -#include "clang/Tooling/FixIt.h" - -using namespace clang::ast_matchers; - -namespace clang { -namespace tidy { -namespace misc { - -AST_MATCHER_P(IntegerLiteral, isBiggerThan, unsigned, N) { - return Node.getValue().getZExtValue() > N; -} - -StringConstructorCheck::StringConstructorCheck(StringRef Name, - ClangTidyContext *Context) - : ClangTidyCheck(Name, Context), - WarnOnLargeLength(Options.get("WarnOnLargeLength", 1) != 0), - LargeLengthThreshold(Options.get("LargeLengthThreshold", 0x800000)) {} - -void StringConstructorCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { - Options.store(Opts, "WarnOnLargeLength", WarnOnLargeLength); - Options.store(Opts, "LargeLengthThreshold", LargeLengthThreshold); -} - -void StringConstructorCheck::registerMatchers(MatchFinder *Finder) { - if (!getLangOpts().CPlusPlus) - return; - - const auto ZeroExpr = expr(ignoringParenImpCasts(integerLiteral(equals(0)))); - const auto CharExpr = expr(ignoringParenImpCasts(characterLiteral())); - const auto NegativeExpr = expr(ignoringParenImpCasts( - unaryOperator(hasOperatorName("-"), - hasUnaryOperand(integerLiteral(unless(equals(0))))))); - const auto LargeLengthExpr = expr(ignoringParenImpCasts( - integerLiteral(isBiggerThan(LargeLengthThreshold)))); - const auto CharPtrType = type(anyOf(pointerType(), arrayType())); - - // Match a string-literal; even through a declaration with initializer. - const auto BoundStringLiteral = stringLiteral().bind("str"); - const auto ConstStrLiteralDecl = varDecl( - isDefinition(), hasType(constantArrayType()), hasType(isConstQualified()), - hasInitializer(ignoringParenImpCasts(BoundStringLiteral))); - const auto ConstPtrStrLiteralDecl = varDecl( - isDefinition(), - hasType(pointerType(pointee(isAnyCharacter(), isConstQualified()))), - hasInitializer(ignoringParenImpCasts(BoundStringLiteral))); - const auto ConstStrLiteral = expr(ignoringParenImpCasts(anyOf( - BoundStringLiteral, declRefExpr(hasDeclaration(anyOf( - ConstPtrStrLiteralDecl, ConstStrLiteralDecl)))))); - - // Check the fill constructor. Fills the string with n consecutive copies of - // character c. [i.e string(size_t n, char c);]. - Finder->addMatcher( - cxxConstructExpr( - hasDeclaration(cxxMethodDecl(hasName("basic_string"))), - hasArgument(0, hasType(qualType(isInteger()))), - hasArgument(1, hasType(qualType(isInteger()))), - anyOf( - // Detect the expression: string('x', 40); - hasArgument(0, CharExpr.bind("swapped-parameter")), - // Detect the expression: string(0, ...); - hasArgument(0, ZeroExpr.bind("empty-string")), - // Detect the expression: string(-4, ...); - hasArgument(0, NegativeExpr.bind("negative-length")), - // Detect the expression: string(0x1234567, ...); - hasArgument(0, LargeLengthExpr.bind("large-length")))) - .bind("constructor"), - this); - - // Check the literal string constructor with char pointer and length - // parameters. [i.e. string (const char* s, size_t n);] - Finder->addMatcher( - cxxConstructExpr( - hasDeclaration(cxxMethodDecl(hasName("basic_string"))), - hasArgument(0, hasType(CharPtrType)), - hasArgument(1, hasType(isInteger())), - anyOf( - // Detect the expression: string("...", 0); - hasArgument(1, ZeroExpr.bind("empty-string")), - // Detect the expression: string("...", -4); - hasArgument(1, NegativeExpr.bind("negative-length")), - // Detect the expression: string("lit", 0x1234567); - hasArgument(1, LargeLengthExpr.bind("large-length")), - // Detect the expression: string("lit", 5) - allOf(hasArgument(0, ConstStrLiteral.bind("literal-with-length")), - hasArgument(1, ignoringParenImpCasts( - integerLiteral().bind("int")))))) - .bind("constructor"), - this); -} - -void StringConstructorCheck::check(const MatchFinder::MatchResult &Result) { - const ASTContext &Ctx = *Result.Context; - const auto *E = Result.Nodes.getNodeAs<CXXConstructExpr>("constructor"); - assert(E && "missing constructor expression"); - SourceLocation Loc = E->getLocStart(); - - if (Result.Nodes.getNodeAs<Expr>("swapped-parameter")) { - const Expr *P0 = E->getArg(0); - const Expr *P1 = E->getArg(1); - diag(Loc, "string constructor parameters are probably swapped;" - " expecting string(count, character)") - << tooling::fixit::createReplacement(*P0, *P1, Ctx) - << tooling::fixit::createReplacement(*P1, *P0, Ctx); - } else if (Result.Nodes.getNodeAs<Expr>("empty-string")) { - diag(Loc, "constructor creating an empty string"); - } else if (Result.Nodes.getNodeAs<Expr>("negative-length")) { - diag(Loc, "negative value used as length parameter"); - } else if (Result.Nodes.getNodeAs<Expr>("large-length")) { - if (WarnOnLargeLength) - diag(Loc, "suspicious large length parameter"); - } else if (Result.Nodes.getNodeAs<Expr>("literal-with-length")) { - const auto *Str = Result.Nodes.getNodeAs<StringLiteral>("str"); - const auto *Lit = Result.Nodes.getNodeAs<IntegerLiteral>("int"); - if (Lit->getValue().ugt(Str->getLength())) { - diag(Loc, "length is bigger then string literal size"); - } - } -} - -} // namespace misc -} // namespace tidy -} // namespace clang |