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 InterfacesGlobalInitCheck::registerMatchers(MatchFinder *Finder) {
  const auto IsGlobal =
      allOf(hasGlobalStorage(),
            hasDeclContext(anyOf(translationUnitDecl(), // Global scope.
                                 namespaceDecl(),       // Namespace scope.
                                 recordDecl())),        // Class scope.
            unless(isConstexpr()));

  const auto ReferencesUndefinedGlobalVar = declRefExpr(hasDeclaration(
      varDecl(IsGlobal, unless(isDefinition())).bind("referencee")));

  Finder->addMatcher(
      varDecl(IsGlobal, isDefinition(),
              hasInitializer(expr(hasDescendant(ReferencesUndefinedGlobalVar))))
          .bind("var"),
      this);
}
void NonConstParameterCheck::registerMatchers(MatchFinder *Finder) {
  // Add parameters to Parameters.
  Finder->addMatcher(parmVarDecl(unless(isInstantiated())).bind("Parm"), this);

  // C++ constructor.
  Finder->addMatcher(cxxConstructorDecl().bind("Ctor"), this);

  // Track unused parameters, there is Wunused-parameter about unused
  // parameters.
  Finder->addMatcher(declRefExpr().bind("Ref"), this);

  // Analyse parameter usage in function.
  Finder->addMatcher(stmt(anyOf(unaryOperator(anyOf(hasOperatorName("++"),
                                                    hasOperatorName("--"))),
                                binaryOperator(), callExpr(), returnStmt(),
                                cxxConstructExpr()))
                         .bind("Mark"),
                     this);
  Finder->addMatcher(varDecl(hasInitializer(anything())).bind("Mark"), this);
}
void MisplacedWideningCastCheck::registerMatchers(MatchFinder *Finder) {
  const auto Calc =
      expr(anyOf(binaryOperator(
                     anyOf(hasOperatorName("+"), hasOperatorName("-"),
                           hasOperatorName("*"), hasOperatorName("<<"))),
                 unaryOperator(hasOperatorName("~"))),
           hasType(isInteger()))
          .bind("Calc");

  const auto ExplicitCast = explicitCastExpr(hasDestinationType(isInteger()),
                                             has(ignoringParenImpCasts(Calc)));
  const auto ImplicitCast =
      implicitCastExpr(hasImplicitDestinationType(isInteger()),
                       has(ignoringParenImpCasts(Calc)));
  const auto Cast = expr(anyOf(ExplicitCast, ImplicitCast)).bind("Cast");

  Finder->addMatcher(varDecl(hasInitializer(Cast)), this);
  Finder->addMatcher(returnStmt(hasReturnValue(Cast)), this);
  Finder->addMatcher(callExpr(hasAnyArgument(Cast)), this);
  Finder->addMatcher(binaryOperator(hasOperatorName("="), hasRHS(Cast)), this);
  Finder->addMatcher(
      binaryOperator(matchers::isComparisonOperator(), hasEitherOperand(Cast)),
      this);
}
StatementMatcher LoopMatcher = 
  forStmt(			// Node
    hasLoopInit(		// Traversal
      declStmt(			// Node
	hasSingleDecl(		// Traversal
	  varDecl(		// Node
            hasInitializer(	// Traversal
	      integerLiteral(	// Node
		equals(		// Narrowing
		  0)))))))).bind("forLoop")
#include "ASTUtility.h" 

// int *x = NULL or int *x = 0
DeclarationMatcher nullPointerMatcher = varDecl(hasType(pointerType()),
        hasInitializer(implicitCastExpr().bind("cast"))).bind("var");

// x == NULL  or x == 0
StatementMatcher biOpMatcher1 = binaryOperator(hasRHS(implicitCastExpr().bind("castR1")),
        hasOperatorName("==")).bind("bo1");

// x != NULL or x != 0
StatementMatcher biOpMatcher2 = binaryOperator(hasRHS(implicitCastExpr().bind("castR2")),
        hasOperatorName("!=")).bind("bo2");

// x != NULL or x != 0
StatementMatcher biOpMatcher3 = binaryOperator(hasRHS(implicitCastExpr().bind("castR3")),
        hasOperatorName("=")).bind("bo3");

class NullPointerPrinter : public MatchFinder::MatchCallback {
public:
    virtual void run(const MatchFinder::MatchResult &Result) 
    {
        //get the node
        clang::ASTContext *Context = Result.Context;
        const clang::ImplicitCastExpr *cast = Result.Nodes.getNodeAs<clang::ImplicitCastExpr>("cast");
        const clang::ImplicitCastExpr *castR1 = Result.Nodes.getNodeAs<clang::ImplicitCastExpr>("castR1");
        const clang::ImplicitCastExpr *castR2 = Result.Nodes.getNodeAs<clang::ImplicitCastExpr>("castR2");
        const clang::ImplicitCastExpr *castR3 = Result.Nodes.getNodeAs<clang::ImplicitCastExpr>("castR3");
        const clang::BinaryOperator *bo1 = Result.Nodes.getNodeAs<clang::BinaryOperator>("bo1");
        const clang::BinaryOperator *bo2 = Result.Nodes.getNodeAs<clang::BinaryOperator>("bo2");
        const clang::BinaryOperator *bo3 = Result.Nodes.getNodeAs<clang::BinaryOperator>("bo3");
示例#7
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();
    }
};
namespace ProgrammingLanguage {

    //match naked new
    DeclarationMatcher nakedNewMatcherPL = varDecl(hasInitializer(newExpr())).bind("var"); 
}