[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