Refactor the check for bad divide into a checker.

Also fix a checker context bug: the Dst set is not always empty initially. 
Because in GRExprEngine::CheckerVisit(), *CurrSet is used repeatedly. 
So we removed the Dst.empty() condition in ~CheckerContext() when deciding
whether to do autotransision.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@80786 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Analysis/GRExprEngine.cpp b/lib/Analysis/GRExprEngine.cpp
index a6b580b..a36916b 100644
--- a/lib/Analysis/GRExprEngine.cpp
+++ b/lib/Analysis/GRExprEngine.cpp
@@ -2700,44 +2700,6 @@
 // Transfer functions: Binary operators.
 //===----------------------------------------------------------------------===//
 
-const GRState* GRExprEngine::CheckDivideZero(Expr* Ex, const GRState* state,
-                                             ExplodedNode* Pred, SVal Denom) {
-  
-  // Divide by undefined? (potentially zero)
-  
-  if (Denom.isUndef()) {
-    ExplodedNode* DivUndef = Builder->generateNode(Ex, state, Pred);
-    
-    if (DivUndef) {
-      DivUndef->markAsSink();
-      ExplicitBadDivides.insert(DivUndef);
-    }
-    
-    return 0;
-  }
-  
-  // Check for divide/remainder-by-zero.
-  // First, "assume" that the denominator is 0 or undefined.            
-  const GRState* zeroState =  state->assume(Denom, false);
-  
-  // Second, "assume" that the denominator cannot be 0.            
-  state = state->assume(Denom, true);
-  
-  // Create the node for the divide-by-zero (if it occurred).  
-  if (zeroState)
-    if (ExplodedNode* DivZeroNode = Builder->generateNode(Ex, zeroState, Pred)) {
-      DivZeroNode->markAsSink();
-      
-      if (state)
-        ImplicitBadDivides.insert(DivZeroNode);
-      else
-        ExplicitBadDivides.insert(DivZeroNode);
-      
-    }
-  
-  return state;
-}
-
 void GRExprEngine::VisitBinaryOperator(BinaryOperator* B,
                                        ExplodedNode* Pred,
                                        ExplodedNodeSet& Dst) {
@@ -2765,10 +2727,14 @@
     
     ExplodedNodeSet Tmp2;
     Visit(RHS, *I1, Tmp2);
+
+    ExplodedNodeSet CheckedSet;
+    CheckerVisit(B, CheckedSet, Tmp2, true);
     
     // With both the LHS and RHS evaluated, process the operation itself.
     
-    for (ExplodedNodeSet::iterator I2=Tmp2.begin(), E2=Tmp2.end(); I2 != E2; ++I2) {
+    for (ExplodedNodeSet::iterator I2=CheckedSet.begin(), E2=CheckedSet.end(); 
+         I2 != E2; ++I2) {
 
       const GRState* state = GetState(*I2);
       const GRState* OldSt = state;
@@ -2799,17 +2765,6 @@
           continue;
         }
           
-        case BinaryOperator::Div:
-        case BinaryOperator::Rem:
-          
-          // Special checking for integer denominators.          
-          if (RHS->getType()->isIntegerType() && 
-              RHS->getType()->isScalarType()) {
-            
-            state = CheckDivideZero(B, state, *I2, RightV);
-            if (!state) continue;
-          }
-          
           // FALL-THROUGH.
 
         default: {
@@ -2875,24 +2830,12 @@
       SVal location = state->getSVal(LHS);
       EvalLoad(Tmp3, LHS, *I2, state, location);
       
-      for (ExplodedNodeSet::iterator I3=Tmp3.begin(), E3=Tmp3.end(); I3!=E3; ++I3) {
+      for (ExplodedNodeSet::iterator I3=Tmp3.begin(), E3=Tmp3.end(); I3!=E3; 
+           ++I3) {
         
         state = GetState(*I3);
         SVal V = state->getSVal(LHS);
 
-        // Check for divide-by-zero.
-        if ((Op == BinaryOperator::Div || Op == BinaryOperator::Rem)
-            && RHS->getType()->isIntegerType()
-            && RHS->getType()->isScalarType()) {
-          
-          // CheckDivideZero returns a new state where the denominator
-          // is assumed to be non-zero.
-          state = CheckDivideZero(B, state, *I3, RightV);
-          
-          if (!state)
-            continue;
-        }
-        
         // Propagate undefined values (left-side).          
         if (V.isUndef()) {
           EvalStore(Dst, B, LHS, *I3, state->BindExpr(B, V),