(original) (raw)

diff --git a/clang/lib/StaticAnalyzer/Checkers/DivZeroChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/DivZeroChecker.cpp index 15d73fb9ca39a..ab90615f63182 100644 --- a/clang/lib/StaticAnalyzer/Checkers/DivZeroChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/DivZeroChecker.cpp @@ -69,7 +69,7 @@ void DivZeroChecker::reportTaintBug( llvm::ArrayRef TaintedSyms) const { if (!TaintedDivChecker.isEnabled()) return; - if (ExplodedNode *N = C.generateNonFatalErrorNode(StateZero)) { + if (ExplodedNode *N = C.generateErrorNode(StateZero)) { auto R = std::make_unique(TaintedDivChecker, Msg, N); bugreporter::trackExpressionValue(N, getDenomExpr(N), *R); @@ -113,9 +113,9 @@ void DivZeroChecker::checkPreStmt(const BinaryOperator *B, if ((stateNotZero && stateZero)) { std::vector taintedSyms = getTaintedSymbols(C.getState(), *DV); if (!taintedSyms.empty()) { - reportTaintBug("Division by a tainted value, possibly zero", stateNotZero, - C, taintedSyms); - return; + reportTaintBug("Division by a tainted value, possibly zero", stateZero, C, + taintedSyms); + // Fallthrough to continue analysis in case of non-zero denominator. } } diff --git a/clang/test/Analysis/taint-generic.c b/clang/test/Analysis/taint-generic.c index 3c520612c5d9b..9d6d2942df4a9 100644 --- a/clang/test/Analysis/taint-generic.c +++ b/clang/test/Analysis/taint-generic.c @@ -412,6 +412,19 @@ int testTaintedDivFP(void) { return 5/x; // x cannot be 0, so no tainted warning either } +void clang_analyzer_warnIfReached(); + +int testTaintDivZeroNonfatal() { + int x; + scanf("%d", &x); + int y = 5/x; // expected-warning {{Division by a tainted value, possibly zero}} + if (x == 0) + clang_analyzer_warnIfReached(); + else + clang_analyzer_warnIfReached(); // expected-warning {{REACHABLE}} + return y; +} + // Zero-sized VLAs. void testTaintedVLASize(void) { int x;