コード例 #1
0
void ContainerSizeEmptyCheck::registerMatchers(MatchFinder *Finder) {
  const auto WrongUse = anyOf(
      hasParent(
          binaryOperator(
              anyOf(has(integerLiteral(equals(0))),
                    allOf(anyOf(hasOperatorName("<"), hasOperatorName(">="),
                                hasOperatorName(">"), hasOperatorName("<=")),
                          hasEitherOperand(integerLiteral(equals(1))))))
              .bind("SizeBinaryOp")),
      hasParent(implicitCastExpr(
          hasImplicitDestinationType(isBoolType()),
          anyOf(
              hasParent(unaryOperator(hasOperatorName("!")).bind("NegOnSize")),
              anything()))),
      hasParent(explicitCastExpr(hasDestinationType(isBoolType()))));

  Finder->addMatcher(
      memberCallExpr(
          on(expr(anyOf(hasType(namedDecl(stlContainer())),
                        hasType(pointsTo(namedDecl(stlContainer()))),
                        hasType(references(namedDecl(stlContainer())))))
                 .bind("STLObject")),
          callee(methodDecl(hasName("size"))), WrongUse).bind("SizeCallExpr"),
      this);
}
void MisplacedOperatorInStrlenInAllocCheck::registerMatchers(
    MatchFinder *Finder) {
  const auto StrLenFunc = functionDecl(anyOf(
      hasName("::strlen"), hasName("::std::strlen"), hasName("::strnlen"),
      hasName("::std::strnlen"), hasName("::strnlen_s"),
      hasName("::std::strnlen_s"), hasName("::wcslen"),
      hasName("::std::wcslen"), hasName("::wcsnlen"), hasName("::std::wcsnlen"),
      hasName("::wcsnlen_s"), hasName("std::wcsnlen_s")));

  const auto BadUse =
      callExpr(callee(StrLenFunc),
               hasAnyArgument(ignoringImpCasts(
                   binaryOperator(
                       hasOperatorName("+"),
                       hasRHS(ignoringParenImpCasts(integerLiteral(equals(1)))))
                       .bind("BinOp"))))
          .bind("StrLen");

  const auto BadArg = anyOf(
      allOf(unless(binaryOperator(
                hasOperatorName("+"), hasLHS(BadUse),
                hasRHS(ignoringParenImpCasts(integerLiteral(equals(1)))))),
            hasDescendant(BadUse)),
      BadUse);

  const auto Alloc0Func =
      functionDecl(anyOf(hasName("::malloc"), hasName("std::malloc"),
                         hasName("::alloca"), hasName("std::alloca")));
  const auto Alloc1Func =
      functionDecl(anyOf(hasName("::calloc"), hasName("std::calloc"),
                         hasName("::realloc"), hasName("std::realloc")));

  const auto Alloc0FuncPtr =
      varDecl(hasType(isConstQualified()),
              hasInitializer(ignoringParenImpCasts(
                  declRefExpr(hasDeclaration(Alloc0Func)))));
  const auto Alloc1FuncPtr =
      varDecl(hasType(isConstQualified()),
              hasInitializer(ignoringParenImpCasts(
                  declRefExpr(hasDeclaration(Alloc1Func)))));

  Finder->addMatcher(callExpr(callee(decl(anyOf(Alloc0Func, Alloc0FuncPtr))),
                              hasArgument(0, BadArg))
                         .bind("Alloc"),
                     this);
  Finder->addMatcher(callExpr(callee(decl(anyOf(Alloc1Func, Alloc1FuncPtr))),
                              hasArgument(1, BadArg))
                         .bind("Alloc"),
                     this);
  Finder->addMatcher(
      cxxNewExpr(isArray(), hasArraySize(BadArg)).bind("Alloc"), this);
}
void PointerAndIntegralOperationCheck::registerMatchers(MatchFinder *Finder) {
  const auto PointerExpr = expr(hasType(pointerType()));
  const auto BoolExpr = ignoringParenImpCasts(hasType(booleanType()));
  const auto CharExpr = ignoringParenImpCasts(hasType(isAnyCharacter()));

  const auto BinOpWithPointerExpr =
      binaryOperator(unless(anyOf(hasOperatorName(","), hasOperatorName("="))),
                     hasEitherOperand(PointerExpr));

  const auto AssignToPointerExpr =
      binaryOperator(hasOperatorName("="), hasLHS(PointerExpr));

  const auto CompareToPointerExpr =
      binaryOperator(matchers::isRelationalOperator(),
                     hasEitherOperand(PointerExpr));

  // Detect expression like: ptr = (x != y);
  Finder->addMatcher(binaryOperator(AssignToPointerExpr, hasRHS(BoolExpr))
                         .bind("assign-bool-to-pointer"),
                     this);

  // Detect expression like: ptr = A[i]; where A is char*.
  Finder->addMatcher(binaryOperator(AssignToPointerExpr, hasRHS(CharExpr))
                         .bind("assign-char-to-pointer"),
                     this);

  // Detect expression like: ptr < false;
  Finder->addMatcher(
      binaryOperator(BinOpWithPointerExpr,
                     hasEitherOperand(ignoringParenImpCasts(cxxBoolLiteral())))
          .bind("pointer-and-bool-literal"),
      this);

  // Detect expression like: ptr < 'a';
  Finder->addMatcher(binaryOperator(BinOpWithPointerExpr,
                                    hasEitherOperand(ignoringParenImpCasts(
                                        characterLiteral())))
                         .bind("pointer-and-char-literal"),
                     this);

  // Detect expression like: ptr < 0;
  Finder->addMatcher(binaryOperator(CompareToPointerExpr,
                                    hasEitherOperand(ignoringParenImpCasts(
                                        integerLiteral(equals(0)))))
                         .bind("compare-pointer-to-zero"),
                     this);

  // Detect expression like: ptr < nullptr;
  Finder->addMatcher(binaryOperator(CompareToPointerExpr,
                                    hasEitherOperand(ignoringParenImpCasts(
                                        cxxNullPtrLiteralExpr())))
                         .bind("compare-pointer-to-null"),
                     this);
}
コード例 #4
0
void ContainerSizeEmptyCheck::registerMatchers(MatchFinder *Finder) {
  // Only register the matchers for C++; the functionality currently does not
  // provide any benefit to other languages, despite being benign.
  if (!getLangOpts().CPlusPlus)
    return;

  const auto ValidContainer = cxxRecordDecl(isSameOrDerivedFrom(
      namedDecl(
          has(cxxMethodDecl(
                  isConst(), parameterCountIs(0), isPublic(), hasName("size"),
                  returns(qualType(isInteger(), unless(booleanType()))))
                  .bind("size")),
          has(cxxMethodDecl(isConst(), parameterCountIs(0), isPublic(),
                            hasName("empty"), returns(booleanType()))
                  .bind("empty")))
          .bind("container")));

  const auto WrongUse = anyOf(
      hasParent(binaryOperator(
                    matchers::isComparisonOperator(),
                    hasEitherOperand(ignoringImpCasts(anyOf(
                        integerLiteral(equals(1)), integerLiteral(equals(0))))))
                    .bind("SizeBinaryOp")),
      hasParent(implicitCastExpr(
          hasImplicitDestinationType(booleanType()),
          anyOf(
              hasParent(unaryOperator(hasOperatorName("!")).bind("NegOnSize")),
              anything()))),
      hasParent(explicitCastExpr(hasDestinationType(booleanType()))));

  Finder->addMatcher(
      cxxMemberCallExpr(on(expr(anyOf(hasType(ValidContainer),
                                      hasType(pointsTo(ValidContainer)),
                                      hasType(references(ValidContainer))))
                               .bind("STLObject")),
                        callee(cxxMethodDecl(hasName("size"))), WrongUse)
          .bind("SizeCallExpr"),
      this);
}
コード例 #5
0
void UseBoolLiteralsCheck::registerMatchers(MatchFinder *Finder) {
  if (!getLangOpts().CPlusPlus)
    return;

  Finder->addMatcher(
      implicitCastExpr(
          has(ignoringParenImpCasts(integerLiteral().bind("literal"))),
          hasImplicitDestinationType(qualType(booleanType())),
          unless(isInTemplateInstantiation()),
          anyOf(hasParent(explicitCastExpr().bind("cast")), anything())),
      this);

  Finder->addMatcher(
      conditionalOperator(
          hasParent(implicitCastExpr(
              hasImplicitDestinationType(qualType(booleanType())),
              unless(isInTemplateInstantiation()))),
          eachOf(hasTrueExpression(
                     ignoringParenImpCasts(integerLiteral().bind("literal"))),
                 hasFalseExpression(
                     ignoringParenImpCasts(integerLiteral().bind("literal"))))),
      this);
}
コード例 #6
0
/// Returns `true` if `Node` is a value which evaluates to a literal `0`.
bool IsLiteralZero(const MatchFinder::MatchResult &Result, const Expr &Node) {
  auto ZeroMatcher =
      anyOf(integerLiteral(equals(0)), floatLiteral(equals(0.0)));

  // Check to see if we're using a zero directly.
  if (selectFirst<const clang::Expr>(
          "val", match(expr(ignoringImpCasts(ZeroMatcher)).bind("val"), Node,
                       *Result.Context)) != nullptr)
    return true;

  // Now check to see if we're using a functional cast with a scalar
  // initializer expression, e.g. `int{0}`.
  if (selectFirst<const clang::Expr>(
          "val", match(cxxFunctionalCastExpr(
                           hasDestinationType(
                               anyOf(isInteger(), realFloatingPointType())),
                           hasSourceExpression(initListExpr(
                               hasInit(0, ignoringParenImpCasts(ZeroMatcher)))))
                           .bind("val"),
                       Node, *Result.Context)) != nullptr)
    return true;

  return false;
}
コード例 #7
0
StatementMatcher LoopMatcher = 
  forStmt(			// Node
    hasLoopInit(		// Traversal
      declStmt(			// Node
	hasSingleDecl(		// Traversal
	  varDecl(		// Node
            hasInitializer(	// Traversal
	      integerLiteral(	// Node
		equals(		// Narrowing
		  0)))))))).bind("forLoop")
コード例 #8
0
void MagicNumbersCheck::registerMatchers(MatchFinder *Finder) {
  Finder->addMatcher(integerLiteral().bind("integer"), this);
  if (!IgnoreAllFloatingPointValues)
    Finder->addMatcher(floatLiteral().bind("float"), this);
}
コード例 #9
0
StatementMatcher LoopMatcher =
    forStmt(hasLoopInit(declStmt(hasSingleDecl(varDecl(
            hasInitializer(integerLiteral(equals(0)))))))).bind("forLoop");

class LoopPrinter : public MatchFinder::MatchCallback {
public :
    virtual void run(const MatchFinder::MatchResult &Result) {
        if (const ForStmt *FS = Result.Nodes.getNodeAs<clang::ForStmt>("forLoop"))
            FS->dump();
    }
};
コード例 #10
0
void SuspiciousStringCompareCheck::registerMatchers(MatchFinder *Finder) {
  // Match relational operators.
  const auto ComparisonUnaryOperator = unaryOperator(hasOperatorName("!"));
  const auto ComparisonBinaryOperator =
      binaryOperator(matchers::isComparisonOperator());
  const auto ComparisonOperator =
      expr(anyOf(ComparisonUnaryOperator, ComparisonBinaryOperator));

  // Add the list of known string compare-like functions and add user-defined
  // functions.
  std::vector<std::string> FunctionNames = utils::options::parseStringList(
      (llvm::Twine(KnownStringCompareFunctions) + StringCompareLikeFunctions)
          .str());

  // Match a call to a string compare functions.
  const auto FunctionCompareDecl =
      functionDecl(hasAnyName(std::vector<StringRef>(FunctionNames.begin(),
                                                     FunctionNames.end())))
          .bind("decl");
  const auto DirectStringCompareCallExpr =
      callExpr(hasDeclaration(FunctionCompareDecl)).bind("call");
  const auto MacroStringCompareCallExpr = conditionalOperator(anyOf(
      hasTrueExpression(ignoringParenImpCasts(DirectStringCompareCallExpr)),
      hasFalseExpression(ignoringParenImpCasts(DirectStringCompareCallExpr))));
  // The implicit cast is not present in C.
  const auto StringCompareCallExpr = ignoringParenImpCasts(
      anyOf(DirectStringCompareCallExpr, MacroStringCompareCallExpr));

  if (WarnOnImplicitComparison) {
    // Detect suspicious calls to string compare:
    //     'if (strcmp())'  ->  'if (strcmp() != 0)'
    Finder->addMatcher(
        stmt(anyOf(ifStmt(hasCondition(StringCompareCallExpr)),
                   whileStmt(hasCondition(StringCompareCallExpr)),
                   doStmt(hasCondition(StringCompareCallExpr)),
                   forStmt(hasCondition(StringCompareCallExpr)),
                   binaryOperator(
                       anyOf(hasOperatorName("&&"), hasOperatorName("||")),
                       hasEitherOperand(StringCompareCallExpr))))
            .bind("missing-comparison"),
        this);
  }

  if (WarnOnLogicalNotComparison) {
    // Detect suspicious calls to string compared with '!' operator:
    //     'if (!strcmp())'  ->  'if (strcmp() == 0)'
    Finder->addMatcher(unaryOperator(hasOperatorName("!"),
                                     hasUnaryOperand(ignoringParenImpCasts(
                                         StringCompareCallExpr)))
                           .bind("logical-not-comparison"),
                       this);
  }

  // Detect suspicious cast to an inconsistant type (i.e. not integer type).
  Finder->addMatcher(
      implicitCastExpr(unless(hasType(isInteger())),
                       hasSourceExpression(StringCompareCallExpr))
          .bind("invalid-conversion"),
      this);

  // Detect suspicious operator with string compare function as operand.
  Finder->addMatcher(
      binaryOperator(
          unless(anyOf(matchers::isComparisonOperator(), hasOperatorName("&&"),
                       hasOperatorName("||"), hasOperatorName("="))),
          hasEitherOperand(StringCompareCallExpr))
          .bind("suspicious-operator"),
      this);

  // Detect comparison to invalid constant: 'strcmp() == -1'.
  const auto InvalidLiteral = ignoringParenImpCasts(
      anyOf(integerLiteral(unless(equals(0))),
            unaryOperator(
                hasOperatorName("-"),
                has(ignoringParenImpCasts(integerLiteral(unless(equals(0)))))),
            characterLiteral(), cxxBoolLiteral()));

  Finder->addMatcher(binaryOperator(matchers::isComparisonOperator(),
                                    hasEitherOperand(StringCompareCallExpr),
                                    hasEitherOperand(InvalidLiteral))
                         .bind("invalid-comparison"),
                     this);
}
コード例 #11
0
ファイル: example.cpp プロジェクト: pysuxing/scholar-slides
StatementMatcher LoopMatcher = 
  forStmt(
    hasLoopInit(
      declStmt(
	hasSingleDecl(
	  varDecl(
            hasInitializer(
	      integerLiteral(
		equals(
                  0)))))))).bind("forLoop")
コード例 #12
0
#include "ExceptNumber.h"
#include "ASTUtility.h"
 

//TODO @TestNeed
static int count = 0;

//Declare a matcher of ASTNode to match magic number set
StatementMatcher FloatLiteralMatcher = floatLiteral().bind("floatliteral");

StatementMatcher IntLiteralMatcher = integerLiteral().bind("intliteral");

StatementMatcher StringLiteralMatcher = stringLiteral().bind("stringliteral");



//Declare a class Inherit clang::ast_matchers::MatchFinder::MatchCallback
class FloatChecker : public MatchFinder::MatchCallback {
public:
	virtual void run(const MatchFinder::MatchResult &Result)
    {
		//get the ASTContext
		clang::ASTContext *Context = Result.Context;
		//get the MagicNumberASTNode
		const clang::FloatingLiteral *fl = Result.Nodes.getNodeAs<clang::FloatingLiteral>("floatliteral");	
		//TODO handle the condition "without vaild data"
		if(!fl || ASTUtility::IsStmtInSTDFile(fl, Context)) return;
        ASTUtility::Print(fl, Context, "Rule049");
	}
};