Don't emit divide-by-zero errors when we divide by an unknown (not
uninitialized) value. At this point we're just too imprecise.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@47636 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/Analysis/GRExprEngine.cpp b/Analysis/GRExprEngine.cpp
index 0630fc5..674454c 100644
--- a/Analysis/GRExprEngine.cpp
+++ b/Analysis/GRExprEngine.cpp
@@ -952,41 +952,44 @@
 
         // Check if the denominator is uninitialized.
         
-        if (RightV.isUninit()) {
-          NodeTy* DivUninit = Builder->generateNode(B, St, N2);
+        if (!RightV.isUnknown()) {
+        
+          if (RightV.isUninit()) {
+            NodeTy* DivUninit = Builder->generateNode(B, St, N2);
+            
+            if (DivUninit) {
+              DivUninit->markAsSink();
+              BadDivides.insert(DivUninit);
+            }
+            
+            continue;
+          }
+            
+          // Check for divide/remainder-by-zero.
+          //
+          // First, "assume" that the denominator is 0 or uninitialized.
           
-          if (DivUninit) {
-            DivUninit->markAsSink();
-            BadDivides.insert(DivUninit);
+          bool isFeasible = false;
+          StateTy ZeroSt =  Assume(St, RightV, false, isFeasible);
+          
+          if (isFeasible) {
+            NodeTy* DivZeroNode = Builder->generateNode(B, ZeroSt, N2);
+            
+            if (DivZeroNode) {
+              DivZeroNode->markAsSink();
+              BadDivides.insert(DivZeroNode);
+            }
           }
           
-          continue;
-        }
+          // Second, "assume" that the denominator cannot be 0.
           
-        // Check for divide/remainder-by-zero.
-        //
-        // First, "assume" that the denominator is 0 or uninitialized.
-        
-        bool isFeasible = false;
-        StateTy ZeroSt =  Assume(St, RightV, false,isFeasible);
-        
-        if (isFeasible) {
-          NodeTy* DivZeroNode = Builder->generateNode(B, ZeroSt, N2);
+          isFeasible = false;
+          St = Assume(St, RightV, true, isFeasible);
           
-          if (DivZeroNode) {
-            DivZeroNode->markAsSink();
-            BadDivides.insert(DivZeroNode);
-          }
+          if (!isFeasible)
+            continue;
         }
         
-        // Second, "assume" that the denominator cannot be 0.
-        
-        isFeasible = false;
-        St = Assume(St, RightV, true, isFeasible);
-        
-        if (!isFeasible)
-          continue;
-        
         // Fall-through.  The logic below processes the divide.
       }
       
@@ -1032,7 +1035,14 @@
           
         default: { 
           
-          assert (B->isCompoundAssignmentOp());                                    
+          assert (B->isCompoundAssignmentOp());
+          
+          if (Op >= BinaryOperator::AndAssign)
+            ((int&) Op) -= (BinaryOperator::AndAssign - BinaryOperator::And);
+          else
+            ((int&) Op) -= BinaryOperator::MulAssign;  
+          
+          // Check if the LHS is uninitialized.
           
           if (LeftV.isUninit()) {
             HandleUninitializedStore(B, N2);
@@ -1058,18 +1068,13 @@
           
           LVal LeftLV = cast<LVal>(LeftV);
           
-          // Propagate uninitialized values (right-side).
-          
-          if (RightV.isUninit()) {
-            St = SetRVal(SetRVal(St, B, RightV), LeftLV, RightV);
-            break;
-          }
-          
           // Fetch the value of the LHS (the value of the variable, etc.).
           
           RVal V = GetRVal(N1->getState(), LeftLV, B->getLHS()->getType());
           
-          // Propagate uninitialized value (left-side).
+          // Propagate uninitialized value (left-side).  We
+          // propogate uninitialized values for the RHS below when
+          // we also check for divide-by-zero.
           
           if (V.isUninit()) {
             St = SetRVal(St, B, V);
@@ -1088,13 +1093,10 @@
             break;
           }
             
-          // Neither the LHS or the RHS have Unknown/Uninit values.  Process
-          // the operation and store the result.
-          
-          if (Op >= BinaryOperator::AndAssign)
-            ((int&) Op) -= (BinaryOperator::AndAssign - BinaryOperator::And);
-          else
-            ((int&) Op) -= BinaryOperator::MulAssign;          
+          // At this point:
+          //
+          //  The LHS is not Uninit/Unknown.
+          //  The RHS is not Unknown.
           
           // Get the computation type.
           QualType CTy = cast<CompoundAssignOperator>(B)->getComputationType();
@@ -1120,7 +1122,7 @@
               
               continue;
             }
-            
+
             // First, "assume" that the denominator is 0.
             
             bool isFeasible = false;
@@ -1145,6 +1147,16 @@
             
             // Fall-through.  The logic below processes the divide.
           }
+          else {
+            
+            // Propagate uninitialized values (right-side).
+            
+            if (RightV.isUninit()) {
+              St = SetRVal(SetRVal(St, B, RightV), LeftLV, RightV);
+              break;
+            }
+            
+          }
 
           RVal Result = EvalCast(EvalBinOp(Op, V, RightV), B->getType());
           St = SetRVal(SetRVal(St, B, Result), LeftLV, Result);