21 using namespace clang;
25 class DivZeroChecker :
public Checker< check::PreStmt<BinaryOperator> > {
26 mutable std::unique_ptr<BuiltinBug> BT;
27 void reportBug(
const char *Msg,
ProgramStateRef StateZero, CheckerContext &C,
28 std::unique_ptr<BugReporterVisitor> Visitor =
nullptr)
const;
31 void checkPreStmt(
const BinaryOperator *B, CheckerContext &C)
const;
36 const Stmt *S = N->getLocationAs<
PreStmt>()->getStmt();
37 if (
const auto *BE = dyn_cast<BinaryOperator>(S))
42 void DivZeroChecker::reportBug(
44 std::unique_ptr<BugReporterVisitor> Visitor)
const {
45 if (ExplodedNode *N = C.generateErrorNode(StateZero)) {
47 BT.reset(
new BuiltinBug(
this,
"Division by zero"));
49 auto R = llvm::make_unique<BugReport>(*BT, Msg, N);
50 R->addVisitor(std::move(Visitor));
51 bugreporter::trackExpressionValue(N,
getDenomExpr(N), *R);
52 C.emitReport(std::move(R));
57 CheckerContext &C)
const {
68 SVal Denom = C.getSVal(B->
getRHS());
77 ConstraintManager &CM = C.getConstraintManager();
79 std::tie(stateNotZero, stateZero) = CM.assumeDual(C.getState(), *DV);
83 reportBug(
"Division by zero", stateZero, C);
87 bool TaintedD = C.getState()->isTainted(*DV);
88 if ((stateNotZero && stateZero && TaintedD)) {
89 reportBug(
"Division by a tainted value, possibly zero", stateZero, C,
90 llvm::make_unique<TaintBugVisitor>(*DV));
96 C.addTransition(stateNotZero);
99 void ento::registerDivZeroChecker(CheckerManager &mgr) {
100 mgr.registerChecker<DivZeroChecker>();
Stmt - This represents one statement.
IntrusiveRefCntPtr< const ProgramState > ProgramStateRef
A builtin binary operation expression such as "x + y" or "x <= y".
bool isScalarType() const
This represents one expression.
Dataflow Directional Tag Classes.
static const Expr * getDenomExpr(const ExplodedNode *N)