[cfe-commits] r48013 - in /cfe/trunk: Analysis/GRExprEngine.cpp Analysis/GRSimpleVals.cpp include/clang/Analysis/PathSensitive/GRExprEngine.h

Ted Kremenek kremenek at apple.com
Fri Mar 7 11:04:54 PST 2008


Author: kremenek
Date: Fri Mar  7 13:04:53 2008
New Revision: 48013

URL: http://llvm.org/viewvc/llvm-project?rev=48013&view=rev
Log:
Refined divide-by-zero checking to distinguish between must and may
divide-by-zero errors.

Modified:
    cfe/trunk/Analysis/GRExprEngine.cpp
    cfe/trunk/Analysis/GRSimpleVals.cpp
    cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h

Modified: cfe/trunk/Analysis/GRExprEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Analysis/GRExprEngine.cpp?rev=48013&r1=48012&r2=48013&view=diff

==============================================================================
--- cfe/trunk/Analysis/GRExprEngine.cpp (original)
+++ cfe/trunk/Analysis/GRExprEngine.cpp Fri Mar  7 13:04:53 2008
@@ -1040,7 +1040,7 @@
             
             if (DivUndef) {
               DivUndef->markAsSink();
-              BadDivides.insert(DivUndef);
+              ExplicitBadDivides.insert(DivUndef);
             }
             
             continue;
@@ -1050,21 +1050,28 @@
           //
           // First, "assume" that the denominator is 0 or undefined.
           
-          bool isFeasible = false;
-          ValueState* ZeroSt =  Assume(St, RightV, false, isFeasible);
+          bool isFeasibleZero = false;
+          ValueState* ZeroSt =  Assume(St, RightV, false, isFeasibleZero);
           
-          if (isFeasible)
+          // Second, "assume" that the denominator cannot be 0.
+          
+          bool isFeasibleNotZero = false;
+          St = Assume(St, RightV, true, isFeasibleNotZero);
+          
+          // Create the node for the divide-by-zero (if it occurred).
+          
+          if (isFeasibleZero)
             if (NodeTy* DivZeroNode = Builder->generateNode(B, ZeroSt, N2)) {
               DivZeroNode->markAsSink();
-              BadDivides.insert(DivZeroNode);
+              
+              if (isFeasibleNotZero)
+                ImplicitBadDivides.insert(DivZeroNode);
+              else
+                ExplicitBadDivides.insert(DivZeroNode);
+
             }
           
-          // Second, "assume" that the denominator cannot be 0.
-          
-          isFeasible = false;
-          St = Assume(St, RightV, true, isFeasible);
-          
-          if (!isFeasible)
+          if (!isFeasibleNotZero)
             continue;
         }
         
@@ -1208,7 +1215,7 @@
               
               if (DivUndef) {
                 DivUndef->markAsSink();
-                BadDivides.insert(DivUndef);
+                ExplicitBadDivides.insert(DivUndef);
               }
               
               continue;
@@ -1216,24 +1223,30 @@
 
             // First, "assume" that the denominator is 0.
             
-            bool isFeasible = false;
-            ValueState* ZeroSt = Assume(St, RightV, false, isFeasible);
+            bool isFeasibleZero = false;
+            ValueState* ZeroSt = Assume(St, RightV, false, isFeasibleZero);
             
-            if (isFeasible) {
+            // Second, "assume" that the denominator cannot be 0.
+            
+            bool isFeasibleNotZero = false;
+            St = Assume(St, RightV, true, isFeasibleNotZero);
+            
+            // Create the node for the divide-by-zero error (if it occurred).
+            
+            if (isFeasibleZero) {
               NodeTy* DivZeroNode = Builder->generateNode(B, ZeroSt, N2);
               
               if (DivZeroNode) {
                 DivZeroNode->markAsSink();
-                BadDivides.insert(DivZeroNode);
+                
+                if (isFeasibleNotZero)
+                  ImplicitBadDivides.insert(DivZeroNode);
+                else
+                  ExplicitBadDivides.insert(DivZeroNode);
               }
             }
             
-            // Second, "assume" that the denominator cannot be 0.
-            
-            isFeasible = false;
-            St = Assume(St, RightV, true, isFeasible);
-            
-            if (!isFeasible)
+            if (!isFeasibleNotZero)
               continue;
             
             // Fall-through.  The logic below processes the divide.
@@ -1659,7 +1672,8 @@
         GraphPrintCheckerState->isUndefDeref(N) ||
         GraphPrintCheckerState->isUndefStore(N) ||
         GraphPrintCheckerState->isUndefControlFlow(N) ||
-        GraphPrintCheckerState->isBadDivide(N) ||
+        GraphPrintCheckerState->isExplicitBadDivide(N) ||
+        GraphPrintCheckerState->isImplicitBadDivide(N) ||
         GraphPrintCheckerState->isUndefResult(N) ||
         GraphPrintCheckerState->isBadCall(N) ||
         GraphPrintCheckerState->isUndefArg(N))
@@ -1702,8 +1716,10 @@
           Out << "\\|Dereference of undefialied value.\\l";
         else if (GraphPrintCheckerState->isUndefStore(N))
           Out << "\\|Store to Undefined LVal.";
-        else if (GraphPrintCheckerState->isBadDivide(N))
-          Out << "\\|Divide-by zero or undefined value.";
+        else if (GraphPrintCheckerState->isExplicitBadDivide(N))
+          Out << "\\|Explicit divide-by zero or undefined value.";
+        else if (GraphPrintCheckerState->isImplicitBadDivide(N))
+          Out << "\\|Implicit divide-by zero or undefined value.";
         else if (GraphPrintCheckerState->isUndefResult(N))
           Out << "\\|Result of operation is undefined.";
         else if (GraphPrintCheckerState->isNoReturnCall(N))

Modified: cfe/trunk/Analysis/GRSimpleVals.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Analysis/GRSimpleVals.cpp?rev=48013&r1=48012&r2=48013&view=diff

==============================================================================
--- cfe/trunk/Analysis/GRSimpleVals.cpp (original)
+++ cfe/trunk/Analysis/GRSimpleVals.cpp Fri Mar  7 13:04:53 2008
@@ -121,8 +121,8 @@
               "Dereference of undefined value.");
   
   EmitWarning(Diag, SrcMgr,
-              CheckerState->bad_divides_begin(),
-              CheckerState->bad_divides_end(),
+              CheckerState->explicit_bad_divides_begin(),
+              CheckerState->explicit_bad_divides_end(),
               "Division by zero/undefined value.");
   
   EmitWarning(Diag, SrcMgr,

Modified: cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h?rev=48013&r1=48012&r2=48013&view=diff

==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h Fri Mar  7 13:04:53 2008
@@ -98,9 +98,15 @@
   ///  taking a dereference on an undefined value.
   BadDerefTy UndefDeref;
 
-  /// BadDivides - Nodes in the ExplodedGraph that result from evaluating
-  ///  a divide-by-zero or divide-by-undefined.
-  BadDividesTy BadDivides;
+  /// ImplicitBadDivides - Nodes in the ExplodedGraph that result from 
+  ///  evaluating a divide or modulo operation where the denominator
+  ///  MAY be zero.
+  BadDividesTy ImplicitBadDivides;
+  
+  /// ExplicitBadDivides - Nodes in the ExplodedGraph that result from 
+  ///  evaluating a divide or modulo operation where the denominator
+  ///  MUST be zero or undefined.
+  BadDividesTy ExplicitBadDivides;
   
   /// UndefResults - Nodes in the ExplodedGraph where the operands are defined
   ///  by the result is not.  Excludes divide-by-zero errors.
@@ -169,8 +175,12 @@
     return N->isSink() && UndefDeref.count(const_cast<NodeTy*>(N)) != 0;
   }
   
-  bool isBadDivide(const NodeTy* N) const {
-    return N->isSink() && BadDivides.count(const_cast<NodeTy*>(N)) != 0; 
+  bool isImplicitBadDivide(const NodeTy* N) const {
+    return N->isSink() && ImplicitBadDivides.count(const_cast<NodeTy*>(N)) != 0; 
+  }
+  
+  bool isExplicitBadDivide(const NodeTy* N) const {
+    return N->isSink() && ExplicitBadDivides.count(const_cast<NodeTy*>(N)) != 0; 
   }
   
   bool isNoReturnCall(const NodeTy* N) const {
@@ -199,8 +209,22 @@
   undef_deref_iterator undef_derefs_end() { return UndefDeref.end(); }
   
   typedef BadDividesTy::iterator bad_divide_iterator;
-  bad_divide_iterator bad_divides_begin() { return BadDivides.begin(); }
-  bad_divide_iterator bad_divides_end() { return BadDivides.end(); }
+
+  bad_divide_iterator explicit_bad_divides_begin() {
+    return ExplicitBadDivides.begin();
+  }
+  
+  bad_divide_iterator explicit_bad_divides_end() {
+    return ExplicitBadDivides.end();
+  }
+  
+  bad_divide_iterator implicit_bad_divides_begin() {
+    return ImplicitBadDivides.begin();
+  }
+  
+  bad_divide_iterator implicit_bad_divides_end() {
+    return ImplicitBadDivides.end();
+  }
   
   typedef UndefResultsTy::iterator undef_result_iterator;
   undef_result_iterator undef_results_begin() { return UndefResults.begin(); }





More information about the cfe-commits mailing list