[cfe-commits] r57855 - in /cfe/trunk: lib/Analysis/GRExprEngine.cpp test/Analysis/misc-ps.m
Ted Kremenek
kremenek at apple.com
Mon Oct 20 16:40:26 PDT 2008
Author: kremenek
Date: Mon Oct 20 18:40:25 2008
New Revision: 57855
URL: http://llvm.org/viewvc/llvm-project?rev=57855&view=rev
Log:
Further improve path-sensitivity with divide-by-zero checking by assuming that a denominator cannot be zero even when the result of an '/' or '%' expression is unknown.
Modified:
cfe/trunk/lib/Analysis/GRExprEngine.cpp
cfe/trunk/test/Analysis/misc-ps.m
Modified: cfe/trunk/lib/Analysis/GRExprEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/GRExprEngine.cpp?rev=57855&r1=57854&r2=57855&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/GRExprEngine.cpp (original)
+++ cfe/trunk/lib/Analysis/GRExprEngine.cpp Mon Oct 20 18:40:25 2008
@@ -1989,8 +1989,8 @@
// Transfer functions: Binary operators.
//===----------------------------------------------------------------------===//
-bool GRExprEngine::CheckDivideZero(Expr* Ex, const GRState* St,
- NodeTy* Pred, SVal Denom) {
+const GRState* GRExprEngine::CheckDivideZero(Expr* Ex, const GRState* St,
+ NodeTy* Pred, SVal Denom) {
// Divide by undefined? (potentially zero)
@@ -2002,7 +2002,7 @@
ExplicitBadDivides.insert(DivUndef);
}
- return true;
+ return 0;
}
// Check for divide/remainder-by-zero.
@@ -2029,7 +2029,7 @@
}
- return !isFeasibleNotZero;
+ return isFeasibleNotZero ? St : 0;
}
void GRExprEngine::VisitBinaryOperator(BinaryOperator* B,
@@ -2059,6 +2059,8 @@
for (NodeSet::iterator I2=Tmp2.begin(), E2=Tmp2.end(); I2 != E2; ++I2) {
const GRState* St = GetState(*I2);
+ const GRState* OldSt = St;
+
SVal RightV = GetSVal(St, RHS);
BinaryOperator::Opcode Op = B->getOpcode();
@@ -2089,11 +2091,11 @@
case BinaryOperator::Div:
case BinaryOperator::Rem:
- // Special checking for integer denominators.
-
- if (RHS->getType()->isIntegerType()
- && CheckDivideZero(B, St, *I2, RightV))
- continue;
+ // Special checking for integer denominators.
+ if (RHS->getType()->isIntegerType()) {
+ St = CheckDivideZero(B, St, *I2, RightV);
+ if (!St) continue;
+ }
// FALL-THROUGH.
@@ -2108,7 +2110,13 @@
SVal Result = EvalBinOp(Op, LeftV, RightV);
if (Result.isUnknown()) {
- Dst.Add(*I2);
+ if (OldSt != St) {
+ // Generate a new node if we have already created a new state.
+ MakeNode(Dst, B, *I2, St);
+ }
+ else
+ Dst.Add(*I2);
+
continue;
}
@@ -2150,6 +2158,18 @@
St = GetState(*I3);
SVal V = GetSVal(St, LHS);
+ // Check for divide-by-zero.
+ if ((Op == BinaryOperator::Div || Op == BinaryOperator::Rem)
+ && RHS->getType()->isIntegerType()) {
+
+ // CheckDivideZero returns a new state where the denominator
+ // is assumed to be non-zero.
+ St = CheckDivideZero(B, St, *I3, RightV);
+
+ if (!St)
+ continue;
+ }
+
// Propagate undefined values (left-side).
if (V.isUndef()) {
EvalStore(Dst, B, LHS, *I3, SetSVal(St, B, V), location, V);
@@ -2176,14 +2196,7 @@
RightV = EvalCast(RightV, CTy);
// Evaluate operands and promote to result type.
-
- if ((Op == BinaryOperator::Div || Op == BinaryOperator::Rem)
- && RHS->getType()->isIntegerType()) {
-
- if (CheckDivideZero(B, St, *I3, RightV))
- continue;
- }
- else if (RightV.isUndef()) {
+ if (RightV.isUndef()) {
// Propagate undefined values (right-side).
EvalStore(Dst, B, LHS, *I3, SetSVal(St, B, RightV), location, RightV);
continue;
Modified: cfe/trunk/test/Analysis/misc-ps.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/misc-ps.m?rev=57855&r1=57854&r2=57855&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/misc-ps.m (original)
+++ cfe/trunk/test/Analysis/misc-ps.m Mon Oct 20 18:40:25 2008
@@ -29,3 +29,17 @@
if (x == 0) x = x / j; // no-warning
}
+void divzeroassume(unsigned x, unsigned j) {
+ x /= j;
+ if (j == 0) x /= 0; // no-warning
+ if (j == 0) x /= j; // no-warning
+ if (j == 0) x = x / 0; // no-warning
+}
+
+void divzeroassumeB(unsigned x, unsigned j) {
+ x = x / j;
+ if (j == 0) x /= 0; // no-warning
+ if (j == 0) x /= j; // no-warning
+ if (j == 0) x = x / 0; // no-warning
+}
+
More information about the cfe-commits
mailing list