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);
               }
             }
             
diff --git a/Analysis/RValues.cpp b/Analysis/RValues.cpp
index 178d794..bc6a75c 100644
--- a/Analysis/RValues.cpp
+++ b/Analysis/RValues.cpp
@@ -214,7 +214,7 @@
   return nonlval::ConcreteInt(ValMgr.getTruthValue(b));
 }
 
-RVal RVal::GetSymbolValue(SymbolManager& SymMgr, ParmVarDecl* D) {
+RVal RVal::GetSymbolValue(SymbolManager& SymMgr, VarDecl* D) {
 
   QualType T = D->getType();
   
diff --git a/Analysis/SymbolManager.cpp b/Analysis/SymbolManager.cpp
index ced5741..dd71dc9 100644
--- a/Analysis/SymbolManager.cpp
+++ b/Analysis/SymbolManager.cpp
@@ -16,17 +16,24 @@
 
 using namespace clang;
 
-SymbolID SymbolManager::getSymbol(ParmVarDecl* D) {
+SymbolID SymbolManager::getSymbol(VarDecl* D) {
+
+  assert (isa<ParmVarDecl>(D) || D->hasGlobalStorage());
+  
   SymbolID& X = DataToSymbol[getKey(D)];
   
   if (!X.isInitialized()) {
     X = SymbolToData.size();
-    SymbolToData.push_back(SymbolDataParmVar(D));
+    
+    if (ParmVarDecl* VD = dyn_cast<ParmVarDecl>(D))
+      SymbolToData.push_back(SymbolDataParmVar(VD));
+    else
+      SymbolToData.push_back(SymbolDataGlobalVar(D));
   }
   
   return X;
-}
-
+}  
+ 
 SymbolID SymbolManager::getContentsOfSymbol(SymbolID sym) {
   SymbolID& X = DataToSymbol[getKey(sym)];
   
@@ -45,6 +52,9 @@
       
     case ParmKind:
       return cast<SymbolDataParmVar>(this)->getDecl()->getType();
+
+    case GlobalKind:
+      return cast<SymbolDataGlobalVar>(this)->getDecl()->getType();
       
     case ContentsOfKind: {
       SymbolID x = cast<SymbolDataContentsOf>(this)->getSymbol();
diff --git a/Analysis/ValueState.cpp b/Analysis/ValueState.cpp
index 75f719a..03b2996 100644
--- a/Analysis/ValueState.cpp
+++ b/Analysis/ValueState.cpp
@@ -78,8 +78,16 @@
   // Iterate over the variable bindings.
 
   for (ValueState::vb_iterator I = St.vb_begin(), E = St.vb_end(); I!=E ; ++I)
-    if (Liveness.isLive(Loc, I.getKey()))
+    if (Liveness.isLive(Loc, I.getKey())) {
       WList.push_back(I.getKey());
+      
+      RVal X = I.getData();
+      
+      for (RVal::symbol_iterator SI = X.symbol_begin(), SE = X.symbol_end(); 
+           SI != SE; ++SI) {        
+        MarkedSymbols.insert(*SI);
+      }
+    }
 
   // Perform the mark-and-sweep.