Added lazy "symbolication" of parameter variables and global variables.
Added recording of divide-by-zero and divide-by-uninitialized nodes.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@47586 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/Analysis/GRExprEngine.cpp b/Analysis/GRExprEngine.cpp
index 6c363b0..fcbe4cc 100644
--- a/Analysis/GRExprEngine.cpp
+++ b/Analysis/GRExprEngine.cpp
@@ -396,6 +396,22 @@
 
 void GRExprEngine::VisitDeclRefExpr(DeclRefExpr* D, NodeTy* Pred, NodeSet& Dst){
 
+  if (VarDecl* VD = dyn_cast<VarDecl>(D->getDecl()))
+    if (VD->hasGlobalStorage() || isa<ParmVarDecl>(VD)) {
+
+      StateTy StOld = Pred->getState();
+      StateTy St = Symbolicate(StOld, VD);
+
+      if (!(St == StOld)) {
+        if (D != CurrentStmt)
+          Nodify(Dst, D, Pred, St);
+        else
+          Nodify(Dst, D, Pred, SetRVal(St, D, GetRVal(St, D)));
+        
+        return;
+      }
+    }
+  
   if (D != CurrentStmt) {
     Dst.Add(Pred); // No-op. Simply propagate the current state unchanged.
     return;
@@ -796,7 +812,20 @@
   
   Ex = Ex->IgnoreParens();
   
-  if (isa<DeclRefExpr>(Ex)) {
+  if (DeclRefExpr* DR = dyn_cast<DeclRefExpr>(Ex)) {
+    
+    if (VarDecl* VD = dyn_cast<VarDecl>(DR->getDecl()))
+      if (VD->hasGlobalStorage() || isa<ParmVarDecl>(VD)) {
+        
+        StateTy StOld = Pred->getState();
+        StateTy St = Symbolicate(StOld, VD);
+        
+        if (!(St == StOld)) {
+          Nodify(Dst, Ex, Pred, St);
+          return;
+        }
+      }
+    
     Dst.Add(Pred);
     return;
   }
@@ -857,20 +886,33 @@
       
       if ((Op == BinaryOperator::Div || Op == BinaryOperator::Rem)
           && RHS->getType()->isIntegerType()) {
+
+        // Check if the denominator is uninitialized.
         
-        // Check for divide/remaindner-by-zero.
-        
-        // First, "assume" that the denominator is 0.
+        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.
         
         bool isFeasible = false;
-        StateTy ZeroSt = Assume(St, RightV, false, isFeasible);
+        StateTy ZeroSt =  Assume(St, RightV, false,isFeasible);
         
         if (isFeasible) {
           NodeTy* DivZeroNode = Builder->generateNode(B, ZeroSt, N2);
           
           if (DivZeroNode) {
             DivZeroNode->markAsSink();
-            DivZeroes.insert(DivZeroNode);
+            BadDivides.insert(DivZeroNode);
           }
         }
         
@@ -1003,8 +1045,19 @@
           if ((Op == BinaryOperator::Div || Op == BinaryOperator::Rem)
               && RHS->getType()->isIntegerType()) {
             
-             // Check for divide/remainder-by-zero.
-                        
+            // Check if the denominator is uninitialized.
+                
+            if (RightV.isUninit()) {
+              NodeTy* DivUninit = Builder->generateNode(B, St, N2);
+              
+              if (DivUninit) {
+                DivUninit->markAsSink();
+                BadDivides.insert(DivUninit);
+              }
+              
+              continue;
+            }
+            
             // First, "assume" that the denominator is 0.
             
             bool isFeasible = false;
@@ -1015,7 +1068,7 @@
               
               if (DivZeroNode) {
                 DivZeroNode->markAsSink();
-                DivZeroes.insert(DivZeroNode);
+                BadDivides.insert(DivZeroNode);
               }
             }