Simplify 'Environment' to contain only one map from 'const Stmt*' to SVals, greatly simplifying the logic of the analyzer in many places.  We now only distinguish between block-level expressions and subexpressions in Environment::RemoveDeadBindings and GRState pretty-printing.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@80194 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Analysis/GRExprEngine.cpp b/lib/Analysis/GRExprEngine.cpp
index 600c52c..41caeaf 100644
--- a/lib/Analysis/GRExprEngine.cpp
+++ b/lib/Analysis/GRExprEngine.cpp
@@ -341,8 +341,7 @@
       }
       else if (B->getOpcode() == BinaryOperator::Comma) {
         const GRState* state = GetState(Pred);
-        MakeNode(Dst, B, Pred, state->bindExpr(B, state->getSVal(B->getRHS()),
-                                               Pred->getCFG()));
+        MakeNode(Dst, B, Pred, state->bindExpr(B, state->getSVal(B->getRHS())));
         break;
       }
 
@@ -459,8 +458,7 @@
                
       if (Expr* LastExpr = dyn_cast<Expr>(*SE->getSubStmt()->body_rbegin())) {
         const GRState* state = GetState(Pred);
-        MakeNode(Dst, SE, Pred, state->bindExpr(SE, state->getSVal(LastExpr),
-                                                Pred->getCFG()));
+        MakeNode(Dst, SE, Pred, state->bindExpr(SE, state->getSVal(LastExpr)));
       }
       else
         Dst.Add(Pred);
@@ -543,7 +541,7 @@
     case Stmt::StringLiteralClass: {
       const GRState* state = GetState(Pred);
       SVal V = state->getLValue(cast<StringLiteral>(Ex));
-      MakeNode(Dst, Ex, Pred, state->bindExpr(Ex, V, Pred->getCFG()));
+      MakeNode(Dst, Ex, Pred, state->bindExpr(Ex, V));
       return;
     }
       
@@ -612,7 +610,7 @@
                  (Op == BinaryOperator::LOr && !branchTaken)  
                ? B->getRHS() : B->getLHS();
         
-      return state->bindBlkExpr(B, UndefinedVal(Ex));
+      return state->bindExpr(B, UndefinedVal(Ex));
     }
       
     case Stmt::ConditionalOperatorClass: { // ?:
@@ -629,7 +627,7 @@
       else
         Ex = C->getRHS();
       
-      return state->bindBlkExpr(C, UndefinedVal(Ex));
+      return state->bindExpr(C, UndefinedVal(Ex));
     }
       
     case Stmt::ChooseExprClass: { // ?:
@@ -637,7 +635,7 @@
       ChooseExpr* C = cast<ChooseExpr>(Terminator);
       
       Expr* Ex = branchTaken ? C->getLHS() : C->getRHS();      
-      return state->bindBlkExpr(C, UndefinedVal(Ex));
+      return state->bindExpr(C, UndefinedVal(Ex));
     }
   }
 }
@@ -684,10 +682,6 @@
 void GRExprEngine::ProcessBranch(Stmt* Condition, Stmt* Term,
                                  GRBranchNodeBuilder& builder) {
   
-  // Remove old bindings for subexpressions.
-  const GRState* PrevState =
-    StateMgr.RemoveSubExprBindings(builder.getState());
-  
   // Check for NULL conditions; e.g. "for(;;)"
   if (!Condition) { 
     builder.markInfeasible(false);
@@ -697,7 +691,8 @@
   PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(),
                                 Condition->getLocStart(),
                                 "Error evaluating branch");
-  
+
+  const GRState* PrevState = builder.getState();  
   SVal V = PrevState->getSVal(Condition);
   
   switch (V.getBaseKind()) {
@@ -808,16 +803,16 @@
   assert (Ex == CurrentStmt && Pred->getLocationContext()->getCFG()->isBlkExpr(Ex));
   
   const GRState* state = GetState(Pred);
-  SVal X = state->getBlkExprSVal(Ex);
+  SVal X = state->getSVal(Ex);
   
   assert (X.isUndef());
   
   Expr *SE = (Expr*) cast<UndefinedVal>(X).getData();
   assert(SE);  
-  X = state->getBlkExprSVal(SE);
+  X = state->getSVal(SE);
   
   // Make sure that we invalidate the previous binding.
-  MakeNode(Dst, Ex, Pred, state->bindExpr(Ex, X, true, true));
+  MakeNode(Dst, Ex, Pred, state->bindExpr(Ex, X, true));
 }
 
 /// ProcessSwitch - Called by GRCoreEngine.  Used to generate successor
@@ -918,7 +913,7 @@
   assert(B == CurrentStmt && Pred->getLocationContext()->getCFG()->isBlkExpr(B));
   
   const GRState* state = GetState(Pred);
-  SVal X = state->getBlkExprSVal(B);
+  SVal X = state->getSVal(B);
   assert(X.isUndef());
   
   Expr* Ex = (Expr*) cast<UndefinedVal>(X).getData();
@@ -927,12 +922,12 @@
   
   if (Ex == B->getRHS()) {
     
-    X = state->getBlkExprSVal(Ex);
+    X = state->getSVal(Ex);
     
     // Handle undefined values.
     
     if (X.isUndef()) {
-      MakeNode(Dst, B, Pred, state->bindBlkExpr(B, X));
+      MakeNode(Dst, B, Pred, state->bindExpr(B, X));
       return;
     }
     
@@ -944,11 +939,11 @@
     // the payoff is not likely to be large.  Instead, we do eager evaluation.        
     if (const GRState *newState = state->assume(X, true))
       MakeNode(Dst, B, Pred, 
-               newState->bindBlkExpr(B, ValMgr.makeIntVal(1U, B->getType())));
+               newState->bindExpr(B, ValMgr.makeIntVal(1U, B->getType())));
       
     if (const GRState *newState = state->assume(X, false))
       MakeNode(Dst, B, Pred, 
-               newState->bindBlkExpr(B, ValMgr.makeIntVal(0U, B->getType())));
+               newState->bindExpr(B, ValMgr.makeIntVal(0U, B->getType())));
   }
   else {
     // We took the LHS expression.  Depending on whether we are '&&' or
@@ -956,7 +951,7 @@
     // the short-circuiting.
     X = ValMgr.makeIntVal(B->getOpcode() == BinaryOperator::LAnd ? 0U : 1U, 
                           B->getType());
-    MakeNode(Dst, B, Pred, state->bindBlkExpr(B, X));
+    MakeNode(Dst, B, Pred, state->bindExpr(B, X));
   }
 }
  
@@ -976,7 +971,7 @@
     SVal V = state->getLValue(VD, Pred->getLocationContext());
 
     if (asLValue)
-      MakeNode(Dst, Ex, Pred, state->bindExpr(Ex, V, Pred->getCFG()),
+      MakeNode(Dst, Ex, Pred, state->bindExpr(Ex, V),
                ProgramPoint::PostLValueKind);
     else
       EvalLoad(Dst, Ex, Pred, state, V);
@@ -986,13 +981,13 @@
     assert(!asLValue && "EnumConstantDecl does not have lvalue.");
 
     SVal V = ValMgr.makeIntVal(ED->getInitVal());
-    MakeNode(Dst, Ex, Pred, state->bindExpr(Ex, V, Pred->getCFG()));
+    MakeNode(Dst, Ex, Pred, state->bindExpr(Ex, V));
     return;
 
   } else if (const FunctionDecl* FD = dyn_cast<FunctionDecl>(D)) {
     assert(asLValue);
     SVal V = ValMgr.getFunctionPointer(FD);
-    MakeNode(Dst, Ex, Pred, state->bindExpr(Ex, V, Pred->getCFG()),
+    MakeNode(Dst, Ex, Pred, state->bindExpr(Ex, V),
              ProgramPoint::PostLValueKind);
     return;
   }
@@ -1030,7 +1025,7 @@
                                 state->getSVal(Idx));
 
       if (asLValue)
-        MakeNode(Dst, A, *I2, state->bindExpr(A, V, Pred->getCFG()),
+        MakeNode(Dst, A, *I2, state->bindExpr(A, V),
                  ProgramPoint::PostLValueKind);
       else
         EvalLoad(Dst, A, *I2, state, V);
@@ -1062,7 +1057,7 @@
     SVal L = state->getLValue(state->getSVal(Base), Field);
 
     if (asLValue)
-      MakeNode(Dst, M, *I, state->bindExpr(M, L, Pred->getCFG()),
+      MakeNode(Dst, M, *I, state->bindExpr(M, L),
                ProgramPoint::PostLValueKind);
     else
       EvalLoad(Dst, M, *I, state, L);
@@ -1146,7 +1141,7 @@
 
   if (location.isUnknown()) {
     // This is important.  We must nuke the old binding.
-    MakeNode(Dst, Ex, Pred, state->bindExpr(Ex, UnknownVal(), Pred->getCFG()),
+    MakeNode(Dst, Ex, Pred, state->bindExpr(Ex, UnknownVal()),
              K, tag);
   }
   else {
@@ -1164,7 +1159,7 @@
     //  V = EvalCast(V, Ex->getType());
     //}
     
-    MakeNode(Dst, Ex, Pred, state->bindExpr(Ex, V, Pred->getCFG()), K, tag);
+    MakeNode(Dst, Ex, Pred, state->bindExpr(Ex, V), K, tag);
   }
 }
 
@@ -1387,16 +1382,14 @@
         ExplodedNode *predNew = *I2;
         const GRState *stateNew = predNew->getState();
         SVal Res = Engine.getValueManager().makeTruthVal(true, CE->getType());
-        Engine.MakeNode(Dst, CE, predNew, stateNew->bindExpr(CE, Res, 
-                                                             Pred->getCFG()));
+        Engine.MakeNode(Dst, CE, predNew, stateNew->bindExpr(CE, Res));
       }
     }
     
     // Were they not equal?
     if (const GRState *stateNotEqual = stateLoad->assume(Cmp, false)) {
       SVal Res = Engine.getValueManager().makeTruthVal(false, CE->getType());
-      Engine.MakeNode(Dst, CE, N, stateNotEqual->bindExpr(CE, Res, 
-                                                          Pred->getCFG()));
+      Engine.MakeNode(Dst, CE, N, stateNotEqual->bindExpr(CE, Res));
     }
   }
       
@@ -1611,7 +1604,7 @@
             // For __builtin_expect, just return the value of the subexpression.
             assert (CE->arg_begin() != CE->arg_end());            
             SVal X = state->getSVal(*(CE->arg_begin()));
-            MakeNode(Dst, CE, *DI, state->bindExpr(CE, X, Pred->getCFG()));
+            MakeNode(Dst, CE, *DI, state->bindExpr(CE, X));
             continue;            
           }
             
@@ -1626,9 +1619,7 @@
             // cannot represent values like symbol*8.
             SVal Extent = state->getSVal(*(CE->arg_begin()));
             state = getStoreManager().setExtent(state, R, Extent);
-
-            MakeNode(Dst, CE, *DI, state->bindExpr(CE, loc::MemRegionVal(R), 
-                                                   Pred->getCFG()));
+            MakeNode(Dst, CE, *DI, state->bindExpr(CE, loc::MemRegionVal(R)));
             continue;            
           }
             
@@ -1701,8 +1692,7 @@
       // First assume that the condition is true.
       if (const GRState *stateTrue = state->assume(V, true)) {
         stateTrue = stateTrue->bindExpr(Ex, 
-                                        ValMgr.makeIntVal(1U, Ex->getType()),
-                                        Pred->getCFG());
+                                        ValMgr.makeIntVal(1U, Ex->getType()));
         Dst.Add(Builder->generateNode(PostStmtCustom(Ex, 
                                 &EagerlyAssumeTag, Pred->getLocationContext()),
                                       stateTrue, Pred));
@@ -1711,8 +1701,7 @@
       // Next, assume that the condition is false.
       if (const GRState *stateFalse = state->assume(V, false)) {
         stateFalse = stateFalse->bindExpr(Ex, 
-                                          ValMgr.makeIntVal(0U, Ex->getType()),
-                                          Pred->getCFG());
+                                          ValMgr.makeIntVal(0U, Ex->getType()));
         Dst.Add(Builder->generateNode(PostStmtCustom(Ex, &EagerlyAssumeTag,
                                                    Pred->getLocationContext()),
                                       stateFalse, Pred));
@@ -1741,7 +1730,7 @@
     SVal location = state->getLValue(Ex->getDecl(), BaseVal);
     
     if (asLValue)
-      MakeNode(Dst, Ex, *I, state->bindExpr(Ex, location, Pred->getCFG()));
+      MakeNode(Dst, Ex, *I, state->bindExpr(Ex, location));
     else
       EvalLoad(Dst, Ex, *I, state, location);
   }
@@ -1817,11 +1806,11 @@
 
   // Handle the case where the container still has elements.
   SVal TrueV = ValMgr.makeTruthVal(1);
-  const GRState *hasElems = state->bindExpr(S, TrueV, Pred->getCFG());
+  const GRState *hasElems = state->bindExpr(S, TrueV);
   
   // Handle the case where the container has no elements.
   SVal FalseV = ValMgr.makeTruthVal(0);
-  const GRState *noElems = state->bindExpr(S, FalseV, Pred->getCFG());
+  const GRState *noElems = state->bindExpr(S, FalseV);
   
   if (loc::MemRegionVal* MV = dyn_cast<loc::MemRegionVal>(&ElementV))
     if (const TypedRegion* R = dyn_cast<TypedRegion>(MV->getRegion())) {
@@ -1973,7 +1962,7 @@
               // of this case unless we have *a lot* more knowledge.
               //
               SVal V = ValMgr.makeZeroVal(ME->getType());
-              MakeNode(Dst, ME, Pred, StNull->bindExpr(ME, V, Pred->getCFG()));
+              MakeNode(Dst, ME, Pred, StNull->bindExpr(ME, V));
               return;
             }
           }
@@ -2110,7 +2099,7 @@
     const GRState* state = GetState(N);
     SVal V = state->getSVal(Ex);
     const SValuator::CastResult &Res = SVator.EvalCast(V, state, T, ExTy);
-    state = Res.getState()->bindExpr(CastE, Res.getSVal(), Pred->getCFG());
+    state = Res.getState()->bindExpr(CastE, Res.getSVal());
     MakeNode(Dst, CastE, N, state);
   }
 }
@@ -2129,10 +2118,9 @@
     state = state->bindCompoundLiteral(CL, ILV);
 
     if (asLValue)
-      MakeNode(Dst, CL, *I, state->bindExpr(CL, state->getLValue(CL), 
-                                            Pred->getCFG()));
+      MakeNode(Dst, CL, *I, state->bindExpr(CL, state->getLValue(CL)));
     else
-      MakeNode(Dst, CL, *I, state->bindExpr(CL, ILV, Pred->getCFG()));
+      MakeNode(Dst, CL, *I, state->bindExpr(CL, ILV));
   }
 }
 
@@ -2256,7 +2244,7 @@
     // e.g: static int* myArray[] = {};
     if (NumInitElements == 0) {
       SVal V = ValMgr.makeCompoundVal(T, StartVals);
-      MakeNode(Dst, E, Pred, state->bindExpr(E, V, Pred->getCFG()));
+      MakeNode(Dst, E, Pred, state->bindExpr(E, V));
       return;
     }      
     
@@ -2291,7 +2279,7 @@
           SVal V = ValMgr.makeCompoundVal(T, NewVals);
 
           // Make final state and node.
-          MakeNode(Dst, E, *NI, state->bindExpr(E, V, (*NI)->getCFG()));
+          MakeNode(Dst, E, *NI, state->bindExpr(E, V));
         }
         else {
           // Still some initializer values to go.  Push them onto the worklist.
@@ -2310,7 +2298,7 @@
     Visit(Init, Pred, Tmp);
     for (ExplodedNodeSet::iterator I = Tmp.begin(), EI = Tmp.end(); I != EI; ++I) {
       state = GetState(*I);
-      MakeNode(Dst, E, *I, state->bindExpr(E, state->getSVal(Init), Pred->getCFG()));
+      MakeNode(Dst, E, *I, state->bindExpr(E, state->getSVal(Init)));
     }
     return;
   }
@@ -2351,8 +2339,7 @@
     amt = getContext().getTypeAlign(T) / 8;
   
   MakeNode(Dst, Ex, Pred,
-           GetState(Pred)->bindExpr(Ex, ValMgr.makeIntVal(amt, Ex->getType()),
-                                    Pred->getCFG()));
+           GetState(Pred)->bindExpr(Ex, ValMgr.makeIntVal(amt, Ex->getType())));
 }
 
 
@@ -2376,7 +2363,7 @@
         SVal location = state->getSVal(Ex);
         
         if (asLValue)
-          MakeNode(Dst, U, *I, state->bindExpr(U, location, (*I)->getCFG()),
+          MakeNode(Dst, U, *I, state->bindExpr(U, location),
                    ProgramPoint::PostLValueKind);
         else
           EvalLoad(Dst, U, *I, state, location);
@@ -2403,7 +2390,7 @@
         // For all other types, UnaryOperator::Real is an identity operation.
         assert (U->getType() == Ex->getType());
         const GRState* state = GetState(*I);
-        MakeNode(Dst, U, *I, state->bindExpr(U, state->getSVal(Ex), (*I)->getCFG()));
+        MakeNode(Dst, U, *I, state->bindExpr(U, state->getSVal(Ex)));
       } 
       
       return;
@@ -2427,7 +2414,7 @@
         assert (Ex->getType()->isIntegerType());
         const GRState* state = GetState(*I);
         SVal X = ValMgr.makeZeroVal(Ex->getType());
-        MakeNode(Dst, U, *I, state->bindExpr(U, X, (*I)->getCFG()));
+        MakeNode(Dst, U, *I, state->bindExpr(U, X));
       }
       
       return;
@@ -2452,7 +2439,7 @@
       
       for (ExplodedNodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {        
         const GRState* state = GetState(*I);
-        MakeNode(Dst, U, *I, state->bindExpr(U, state->getSVal(Ex), (*I)->getCFG()));
+        MakeNode(Dst, U, *I, state->bindExpr(U, state->getSVal(Ex)));
       }
       
       return;
@@ -2468,7 +2455,7 @@
       for (ExplodedNodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {        
         const GRState* state = GetState(*I);
         SVal V = state->getSVal(Ex);
-        state = state->bindExpr(U, V, (*I)->getCFG());
+        state = state->bindExpr(U, V);
         MakeNode(Dst, U, *I, state);
       }
 
@@ -2491,7 +2478,7 @@
         SVal V = state->getSVal(Ex);
 
         if (V.isUnknownOrUndef()) {
-          MakeNode(Dst, U, *I, state->bindExpr(U, V, (*I)->getCFG()));
+          MakeNode(Dst, U, *I, state->bindExpr(U, V));
           continue;
         }
         
@@ -2513,13 +2500,12 @@
             
           case UnaryOperator::Not:
             // FIXME: Do we need to handle promotions?
-            state = state->bindExpr(U, EvalComplement(cast<NonLoc>(V)), 
-                                    (*I)->getCFG());
+            state = state->bindExpr(U, EvalComplement(cast<NonLoc>(V)));
             break;            
             
           case UnaryOperator::Minus:
             // FIXME: Do we need to handle promotions?
-            state = state->bindExpr(U, EvalMinus(cast<NonLoc>(V)), (*I)->getCFG());
+            state = state->bindExpr(U, EvalMinus(cast<NonLoc>(V)));
             break;   
             
           case UnaryOperator::LNot:   
@@ -2541,7 +2527,7 @@
                                  U->getType());
             }
             
-            state = state->bindExpr(U, Result, (*I)->getCFG());
+            state = state->bindExpr(U, Result);
             
             break;
         }
@@ -2576,7 +2562,7 @@
         
       // Propagate unknown and undefined values.      
       if (V2.isUnknownOrUndef()) {
-        MakeNode(Dst, U, *I2, state->bindExpr(U, V2, (*I2)->getCFG()));
+        MakeNode(Dst, U, *I2, state->bindExpr(U, V2));
         continue;
       }
       
@@ -2622,7 +2608,7 @@
         }        
       }
       
-      state = state->bindExpr(U, U->isPostfix() ? V2 : Result, (*I2)->getCFG());
+      state = state->bindExpr(U, U->isPostfix() ? V2 : Result);
 
       // Perform the store.      
       EvalStore(Dst, U, *I2, state, V1, Result);
@@ -2846,7 +2832,7 @@
           
           // Simulate the effects of a "store":  bind the value of the RHS
           // to the L-Value represented by the LHS.          
-          EvalStore(Dst, B, LHS, *I2, state->bindExpr(B, RightV, (*I2)->getCFG()), 
+          EvalStore(Dst, B, LHS, *I2, state->bindExpr(B, RightV), 
                     LeftV, RightV);
           continue;
         }
@@ -2889,7 +2875,7 @@
             // The operands were *not* undefined, but the result is undefined.
             // This is a special node that should be flagged as an error.
             
-            if (ExplodedNode* UndefNode = Builder->generateNode(B, state, *I2)) {
+            if (ExplodedNode* UndefNode = Builder->generateNode(B, state, *I2)){
               UndefNode->markAsSink();            
               UndefResults.insert(UndefNode);
             }
@@ -2899,7 +2885,7 @@
           
           // Otherwise, create a new node.
           
-          MakeNode(Dst, B, *I2, state->bindExpr(B, Result, (*I2)->getCFG()));
+          MakeNode(Dst, B, *I2, state->bindExpr(B, Result));
           continue;
         }
       }
@@ -2947,15 +2933,15 @@
         
         // Propagate undefined values (left-side).          
         if (V.isUndef()) {
-          EvalStore(Dst, B, LHS, *I3, state->bindExpr(B, V, (*I3)->getCFG()), 
+          EvalStore(Dst, B, LHS, *I3, state->bindExpr(B, V), 
                     location, V);
           continue;
         }
         
         // Propagate unknown values (left and right-side).
         if (RightV.isUnknown() || V.isUnknown()) {
-          EvalStore(Dst, B, LHS, *I3, state->bindExpr(B, UnknownVal(), 
-                    (*I3)->getCFG()), location, UnknownVal());
+          EvalStore(Dst, B, LHS, *I3, state->bindExpr(B, UnknownVal()),
+                    location, UnknownVal());
           continue;
         }
 
@@ -2982,8 +2968,8 @@
         // Evaluate operands and promote to result type.                    
         if (RightV.isUndef()) {            
           // Propagate undefined values (right-side).          
-          EvalStore(Dst, B, LHS, *I3, state->bindExpr(B, RightV, (*I3)->getCFG()), 
-                    location, RightV);
+          EvalStore(Dst, B, LHS, *I3, state->bindExpr(B, RightV), location,
+                    RightV);
           continue;
         }
       
@@ -3028,7 +3014,7 @@
           llvm::tie(state, LHSVal) = SVator.EvalCast(Result, state, LTy, CTy);
         }
           
-        EvalStore(Dst, B, LHS, *I3, state->bindExpr(B, Result, (*I3)->getCFG()), 
+        EvalStore(Dst, B, LHS, *I3, state->bindExpr(B, Result), 
                   location, LHSVal);
       }
     }