[clang] 2d336e7 - [analyzer] Avoid contradicting assumption in tainted div-by-0 error node (#144491)
via cfe-commits
cfe-commits at lists.llvm.org
Tue Jun 17 04:07:48 PDT 2025
Author: Arseniy Zaostrovnykh
Date: 2025-06-17T13:07:44+02:00
New Revision: 2d336e7c5e821383816a9dca080f713747cc9e1e
URL: https://github.com/llvm/llvm-project/commit/2d336e7c5e821383816a9dca080f713747cc9e1e
DIFF: https://github.com/llvm/llvm-project/commit/2d336e7c5e821383816a9dca080f713747cc9e1e.diff
LOG: [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
https://github.com/llvm/llvm-project/pull/106389/commits/91ac5ed10a154410c246d985752c1bbfcf23b105
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
Added:
Modified:
clang/lib/StaticAnalyzer/Checkers/DivZeroChecker.cpp
clang/test/Analysis/taint-generic.c
Removed:
################################################################################
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<SymbolRef> TaintedSyms) const {
if (!TaintedDivChecker.isEnabled())
return;
- if (ExplodedNode *N = C.generateNonFatalErrorNode(StateZero)) {
+ if (ExplodedNode *N = C.generateErrorNode(StateZero)) {
auto R =
std::make_unique<PathSensitiveBugReport>(TaintedDivChecker, Msg, N);
bugreporter::trackExpressionValue(N, getDenomExpr(N), *R);
@@ -113,9 +113,9 @@ void DivZeroChecker::checkPreStmt(const BinaryOperator *B,
if ((stateNotZero && stateZero)) {
std::vector<SymbolRef> 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;
More information about the cfe-commits
mailing list