[cfe-dev] [help wanted] Implemented a simple Clang Static Checker, but finished executing after only finding one bug

JunDong Xie via cfe-dev cfe-dev at lists.llvm.org
Wed Sep 4 21:02:49 PDT 2019


Hello everyone!
I implemented a simple Clang static analysis checker to detect if there are two integer variables added in the program, because adding two integers may overflow. However, during the execution of the checker, it reports immediately to the user once it encounters the first bug, and then exits. I want it to continue to run and report all bugs. Refer to this link http://clang-analyzer.llvm.org/checker_dev_manual.html#links , I used the addTransition function to generate an ExplodedNode and pass it to the BugReport constructor, but it didn't work. I also tried the generateNonFatalErrorNode function and it didn't work too. Can someone help me to see where is the problem? Thanks very much! Below is the code related to my error report
```
ExplodedNode *N = C.generateNonFatalErrorNode();
  if (!N)
    return;
  auto R = std::make_unique<BugReport>(*BT, BT->getName(), N);
  R->addRange(binOp->getSourceRange());
  C.emitReport(std::move(R));
```

Below is the whole code of my project;
```
using namespace clang;
using namespace ento;


bool IsPureIntType(Expr *expr);
bool IsPureIntType(Expr *expr)
{
  if (expr->getType()->isIntegerType() && !expr->getType()->isEnumeralType() && !expr->getType()->isBooleanType())
  {
    return true;
  }
  return false;
}

namespace
{

class IntegerAddOverFlowChecker : public Checker<check::PreStmt<BinaryOperator>>
{
  mutable std::unique_ptr<BugType> BT;

  public:
    IntegerAddOverFlowChecker();
    void checkPreStmt(const BinaryOperator *binOp, CheckerContext &C) const;
  };
} // namespace

IntegerAddOverFlowChecker::IntegerAddOverFlowChecker() {
    BT.reset(new BuiltinBug(this, "two integer add may overflow!"));
}

void IntegerAddOverFlowChecker::checkPreStmt(const BinaryOperator *binOp, CheckerContext &C) const
{
  if (binOp->getOpcode() != BinaryOperatorKind::BO_AddAssign && binOp->getOpcode() != BinaryOperatorKind::BO_Add)
  {
    return;
  }

  if (binOp->getOpcode() == BinaryOperatorKind::BO_AddAssign)
  {

    if (!IsPureIntType(binOp->getRHS()))
    {
      return;
    }

    if (!IsPureIntType(binOp->getLHS()))
    {
      return;
    }

    SVal RV = C.getSVal(binOp->getRHS());
    if (RV.isConstant())
    {
      return;
    }
  }
  else if (binOp->getOpcode() == BinaryOperatorKind::BO_Add)
  {
    if (!IsPureIntType(binOp->getRHS()))
    {
      return;
    }

    if (!IsPureIntType(binOp->getLHS()))
    {
      return;
    }

    SVal LV = C.getSVal(binOp->getLHS());
    SVal RV = C.getSVal(binOp->getRHS());
    if (LV.isConstant() || RV.isConstant())
    {
      return;
    }
  }
  ExplodedNode *N = C.generateNonFatalErrorNode();
  if (!N)
    return;
  auto R = std::make_unique<BugReport>(*BT, BT->getName(), N);
  R->addRange(binOp->getSourceRange());
  C.emitReport(std::move(R));
}

extern "C" void clang_registerCheckers(CheckerRegistry &registry)
{
  registry.addChecker<IntegerAddOverFlowChecker>("alpha.core.IntegerAddOverFlowChecker", "Checks for two integer add may cause overflow", "NULL");
}

extern "C" const char clang_analyzerAPIVersionString[] = CLANG_ANALYZER_API_VERSION_STRING;
```




More information about the cfe-dev mailing list