Skip to content

Commit 2d336e7

Browse files
authored
[analyzer] Avoid contradicting assumption in tainted div-by-0 error node (#144491)
This patch corrects the state of the error node generated by the core.DivideZero checker when it detects potential division by zero involving a tainted denominator. The checker split in 91ac5ed started to introduce a conflicting assumption about the denominator into the error node: Node with the Bug Report "Division by a tainted value, possibly zero" has an assumption "denominator != 0". This has been done as a shortcut to continue analysis with the correct assumption *after* the division - if we proceed, we can only assume the denominator was not zero. However, this assumption is introduced one-node too soon, leading to a self-contradictory error node. In this patch, I make the error node with assumption of zero denominator fatal, but allow analysis to continue on the second half of the state split with the assumption of non-zero denominator. --- CPP-6376
1 parent 49c6235 commit 2d336e7

File tree

2 files changed

+17
-4
lines changed

2 files changed

+17
-4
lines changed

clang/lib/StaticAnalyzer/Checkers/DivZeroChecker.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ void DivZeroChecker::reportTaintBug(
6969
llvm::ArrayRef<SymbolRef> TaintedSyms) const {
7070
if (!TaintedDivChecker.isEnabled())
7171
return;
72-
if (ExplodedNode *N = C.generateNonFatalErrorNode(StateZero)) {
72+
if (ExplodedNode *N = C.generateErrorNode(StateZero)) {
7373
auto R =
7474
std::make_unique<PathSensitiveBugReport>(TaintedDivChecker, Msg, N);
7575
bugreporter::trackExpressionValue(N, getDenomExpr(N), *R);
@@ -113,9 +113,9 @@ void DivZeroChecker::checkPreStmt(const BinaryOperator *B,
113113
if ((stateNotZero && stateZero)) {
114114
std::vector<SymbolRef> taintedSyms = getTaintedSymbols(C.getState(), *DV);
115115
if (!taintedSyms.empty()) {
116-
reportTaintBug("Division by a tainted value, possibly zero", stateNotZero,
117-
C, taintedSyms);
118-
return;
116+
reportTaintBug("Division by a tainted value, possibly zero", stateZero, C,
117+
taintedSyms);
118+
// Fallthrough to continue analysis in case of non-zero denominator.
119119
}
120120
}
121121

clang/test/Analysis/taint-generic.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -412,6 +412,19 @@ int testTaintedDivFP(void) {
412412
return 5/x; // x cannot be 0, so no tainted warning either
413413
}
414414

415+
void clang_analyzer_warnIfReached();
416+
417+
int testTaintDivZeroNonfatal() {
418+
int x;
419+
scanf("%d", &x);
420+
int y = 5/x; // expected-warning {{Division by a tainted value, possibly zero}}
421+
if (x == 0)
422+
clang_analyzer_warnIfReached();
423+
else
424+
clang_analyzer_warnIfReached(); // expected-warning {{REACHABLE}}
425+
return y;
426+
}
427+
415428
// Zero-sized VLAs.
416429
void testTaintedVLASize(void) {
417430
int x;

0 commit comments

Comments
 (0)