|
@@ -24,11 +24,31 @@ using namespace ento;
|
|
|
namespace {
|
|
|
class DivZeroChecker : public Checker< check::PreStmt<BinaryOperator> > {
|
|
|
mutable llvm::OwningPtr<BuiltinBug> BT;
|
|
|
+ void reportBug(const char *Msg,
|
|
|
+ const ProgramState *StateZero,
|
|
|
+ CheckerContext &C) const ;
|
|
|
public:
|
|
|
void checkPreStmt(const BinaryOperator *B, CheckerContext &C) const;
|
|
|
};
|
|
|
} // end anonymous namespace
|
|
|
|
|
|
+void DivZeroChecker::reportBug(const char *Msg,
|
|
|
+ const ProgramState *StateZero,
|
|
|
+ CheckerContext &C) const {
|
|
|
+ if (ExplodedNode *N = C.generateSink(StateZero)) {
|
|
|
+ if (!BT)
|
|
|
+ BT.reset(new BuiltinBug(Msg));
|
|
|
+
|
|
|
+ BugReport *R =
|
|
|
+ new BugReport(*BT, BT->getDescription(), N);
|
|
|
+
|
|
|
+ R->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N,
|
|
|
+ bugreporter::GetDenomExpr(N)));
|
|
|
+
|
|
|
+ C.EmitReport(R);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
void DivZeroChecker::checkPreStmt(const BinaryOperator *B,
|
|
|
CheckerContext &C) const {
|
|
|
BinaryOperator::Opcode Op = B->getOpcode();
|
|
@@ -57,18 +77,13 @@ void DivZeroChecker::checkPreStmt(const BinaryOperator *B,
|
|
|
|
|
|
if (!stateNotZero) {
|
|
|
assert(stateZero);
|
|
|
- if (ExplodedNode *N = C.generateSink(stateZero)) {
|
|
|
- if (!BT)
|
|
|
- BT.reset(new BuiltinBug("Division by zero"));
|
|
|
-
|
|
|
- BugReport *R =
|
|
|
- new BugReport(*BT, BT->getDescription(), N);
|
|
|
-
|
|
|
- R->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N,
|
|
|
- bugreporter::GetDenomExpr(N)));
|
|
|
+ reportBug("Division by zero", stateZero, C);
|
|
|
+ return;
|
|
|
+ }
|
|
|
|
|
|
- C.EmitReport(R);
|
|
|
- }
|
|
|
+ bool TaintedD = C.getState()->isTainted(*DV);
|
|
|
+ if ((stateNotZero && stateZero && TaintedD)) {
|
|
|
+ reportBug("Division by a tainted value, possibly zero", stateZero, C);
|
|
|
return;
|
|
|
}
|
|
|
|