void MisleadingIndentationCheck::registerMatchers(MatchFinder *Finder) {
  Finder->addMatcher(ifStmt(hasElse(stmt())).bind("if"), this);
  Finder->addMatcher(
      compoundStmt(has(stmt(anyOf(ifStmt(), forStmt(), whileStmt()))))
          .bind("compound"),
      this);
}
void MustUseChecker::registerMatchers(MatchFinder *AstMatcher) {
  AstMatcher->addMatcher(switchCase().bind("switchcase"), this);
  AstMatcher->addMatcher(compoundStmt().bind("compound"), this);
  AstMatcher->addMatcher(ifStmt().bind("if"), this);
  AstMatcher->addMatcher(whileStmt().bind("while"), this);
  AstMatcher->addMatcher(doStmt().bind("do"), this);
  AstMatcher->addMatcher(forStmt().bind("for"), this);
  AstMatcher->addMatcher(binaryOperator(binaryCommaOperator()).bind("bin"),
                         this);
}
Example #3
0
TEST_F(TestIRStmt, TestForStmtWithTwoCondStmts)
{
    IRTypes types;
    IRValue* condVar =
        new IRLocalVar("cond", types.GetBoolTy(), kIRUniform, NULL);
    IRStmt* condStmt = MakeBlock(&types, true);
    IRStmt* iterateStmt = new IRSeq();
    IRStmt* body = MakeBlock(&types, true);
    IRForLoop forStmt(condStmt, condVar, iterateStmt, body, IRPos());
    std::cout << forStmt;
}
void AvoidGotoCheck::registerMatchers(MatchFinder *Finder) {
  if (!getLangOpts().CPlusPlus)
    return;

  // TODO: This check does not recognize `IndirectGotoStmt` which is a
  // GNU extension. These must be matched separately and an AST matcher
  // is currently missing for them.

  // Check if the 'goto' is used for control flow other than jumping
  // out of a nested loop.
  auto Loop = stmt(anyOf(forStmt(), cxxForRangeStmt(), whileStmt(), doStmt()));
  auto NestedLoop =
      stmt(anyOf(forStmt(hasAncestor(Loop)), cxxForRangeStmt(hasAncestor(Loop)),
                 whileStmt(hasAncestor(Loop)), doStmt(hasAncestor(Loop))));

  Finder->addMatcher(gotoStmt(anyOf(unless(hasAncestor(NestedLoop)),
                                    unless(isForwardJumping())))
                         .bind("goto"),
                     this);
}
Example #5
0
void FunctionSizeCheck::registerMatchers(MatchFinder *Finder) {
  Finder->addMatcher(
      functionDecl(
          unless(isInstantiated()),
          forEachDescendant(
              stmt(unless(compoundStmt()),
                   hasParent(stmt(anyOf(compoundStmt(), ifStmt(),
                                        anyOf(whileStmt(), doStmt(),
                                              forRangeStmt(), forStmt())))))
                  .bind("stmt"))).bind("func"),
      this);
}
void InefficientStringConcatenationCheck::registerMatchers(
    MatchFinder *Finder) {
  if (!getLangOpts().CPlusPlus)
    return;

  const auto BasicStringType =
      hasType(qualType(hasUnqualifiedDesugaredType(recordType(
          hasDeclaration(cxxRecordDecl(hasName("::std::basic_string")))))));

  const auto BasicStringPlusOperator = cxxOperatorCallExpr(
      hasOverloadedOperatorName("+"),
      hasAnyArgument(ignoringImpCasts(declRefExpr(BasicStringType))));

  const auto PlusOperator =
      cxxOperatorCallExpr(
          hasOverloadedOperatorName("+"),
          hasAnyArgument(ignoringImpCasts(declRefExpr(BasicStringType))),
          hasDescendant(BasicStringPlusOperator))
          .bind("plusOperator");

  const auto AssignOperator = cxxOperatorCallExpr(
      hasOverloadedOperatorName("="),
      hasArgument(0, declRefExpr(BasicStringType,
                                 hasDeclaration(decl().bind("lhsStrT")))
                         .bind("lhsStr")),
      hasArgument(1, stmt(hasDescendant(declRefExpr(
                         hasDeclaration(decl(equalsBoundNode("lhsStrT"))))))),
      hasDescendant(BasicStringPlusOperator));

  if (StrictMode) {
    Finder->addMatcher(cxxOperatorCallExpr(anyOf(AssignOperator, PlusOperator)),
                       this);
  } else {
    Finder->addMatcher(
        cxxOperatorCallExpr(anyOf(AssignOperator, PlusOperator),
                            hasAncestor(stmt(anyOf(cxxForRangeStmt(),
                                                   whileStmt(), forStmt())))),
        this);
  }
}
Example #7
0
TEST_F(TestIRStmt, TestForStmtWithComplexIterStmt)
{
    IRTypes types;

    IRValue* ifVar =
        new IRLocalVar("p", types.GetBoolTy(), kIRUniform, NULL);
    IRStmt* thenStmt = MakeBlock(&types);
    IRStmt* elseStmt = new IRSeq();
    IRIfStmt* ifStmt = new IRIfStmt(ifVar, thenStmt, elseStmt, IRPos());

    IRStmts* stmts = new IRStmts;
    stmts->push_back(ifStmt);
    stmts->push_back(MakeBlock(&types, true));
    IRStmt* seq = new IRSeq(stmts);

    IRValue* loopVar =
        new IRLocalVar("cond", types.GetBoolTy(), kIRUniform, NULL);
    IRStmt* condStmt = new IRSeq();
    IRStmt* iterateStmt = seq;
    IRStmt* body = MakeBlock(&types);
    IRForLoop forStmt(condStmt, loopVar, iterateStmt, body, IRPos());
    std::cout << forStmt;
}    
Example #8
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();
    }
};
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);
}
void FloatLoopCounter::registerMatchers(MatchFinder *Finder) {
  Finder->addMatcher(
      forStmt(hasIncrement(expr(hasType(realFloatingPointType())))).bind("for"),
      this);
}