]> granicus.if.org Git - clang/commitdiff
Simplify 'Environment' to contain only one map from 'const Stmt*' to SVals, greatly...
authorTed Kremenek <kremenek@apple.com>
Thu, 27 Aug 2009 01:39:13 +0000 (01:39 +0000)
committerTed Kremenek <kremenek@apple.com>
Thu, 27 Aug 2009 01:39:13 +0000 (01:39 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@80194 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Analysis/PathSensitive/Environment.h
include/clang/Analysis/PathSensitive/GRState.h
lib/Analysis/CFRefCount.cpp
lib/Analysis/Environment.cpp
lib/Analysis/GRExprEngine.cpp
lib/Analysis/GRState.cpp

index 6f8a126427699e37798fef7490241e3634340410..f4d36c3550385ac5f805c802fbe0a288534a3aae 100644 (file)
 
 namespace clang {
 
+class AnalysisContext;
 class EnvironmentManager;
 class ValueManager;
 class LiveVariables;
 
+
 class Environment {
 private:
   friend class EnvironmentManager;
@@ -38,47 +40,27 @@ private:
   typedef llvm::ImmutableMap<const Stmt*,SVal> BindingsTy;
 
   // Data.
-  BindingsTy SubExprBindings;
-  BindingsTy BlkExprBindings;
+  BindingsTy ExprBindings;
   
-  Environment(BindingsTy seb, BindingsTy beb)
-    : SubExprBindings(seb), BlkExprBindings(beb) {}
+  Environment(BindingsTy eb)
+    : ExprBindings(eb) {}
   
-public:
+public:    
+  typedef BindingsTy::iterator iterator;
+  iterator begin() const { return ExprBindings.begin(); }
+  iterator end() const { return ExprBindings.end(); }
     
-  typedef BindingsTy::iterator seb_iterator;
-  seb_iterator seb_begin() const { return SubExprBindings.begin(); }
-  seb_iterator seb_end() const { return SubExprBindings.end(); }
-  
-  typedef BindingsTy::iterator beb_iterator;
-  beb_iterator beb_begin() const { return BlkExprBindings.begin(); }
-  beb_iterator beb_end() const { return BlkExprBindings.end(); }      
-  
-  SVal LookupSubExpr(const Stmt* E) const {
-    const SVal* X = SubExprBindings.lookup(cast<Expr>(E));
-    return X ? *X : UnknownVal();
-  }
-  
-  SVal LookupBlkExpr(const Stmt* E) const {
-    const SVal* X = BlkExprBindings.lookup(E);
-    return X ? *X : UnknownVal();
-  }
-  
   SVal LookupExpr(const Stmt* E) const {
-    const SVal* X = SubExprBindings.lookup(E);
-    if (X) return *X;
-    X = BlkExprBindings.lookup(E);
+    const SVal* X = ExprBindings.lookup(E);
     return X ? *X : UnknownVal();
   }
   
   SVal GetSVal(const Stmt* Ex, ValueManager& ValMgr) const;
-  SVal GetBlkExprSVal(const Stmt* Ex, ValueManager& ValMgr) const; 
   
   /// Profile - Profile the contents of an Environment object for use
   ///  in a FoldingSet.
   static void Profile(llvm::FoldingSetNodeID& ID, const Environment* E) {
-    E->SubExprBindings.Profile(ID);
-    E->BlkExprBindings.Profile(ID);
+    E->ExprBindings.Profile(ID);
   }
   
   /// Profile - Used to profile the contents of this object for inclusion
@@ -88,8 +70,7 @@ public:
   }
   
   bool operator==(const Environment& RHS) const {
-    return SubExprBindings == RHS.SubExprBindings &&
-           BlkExprBindings == RHS.BlkExprBindings;
+    return ExprBindings == RHS.ExprBindings;
   }
 };
   
@@ -98,51 +79,20 @@ private:
   typedef Environment::BindingsTy::Factory FactoryTy;
   FactoryTy F;
   
-public:
-  
+public:  
   EnvironmentManager(llvm::BumpPtrAllocator& Allocator) : F(Allocator) {}
   ~EnvironmentManager() {}
-
-  /// RemoveBlkExpr - Return a new environment object with the same bindings as
-  ///  the provided environment except with any bindings for the provided Stmt*
-  ///  removed.  This method only removes bindings for block-level expressions.
-  ///  Using this method on a non-block level expression will return the
-  ///  same environment object.
-  Environment RemoveBlkExpr(const Environment& Env, const Stmt* E) {
-    return Environment(Env.SubExprBindings, F.Remove(Env.BlkExprBindings, E));
-  }
-  
-  Environment RemoveSubExpr(const Environment& Env, const Stmt* E) {
-    return Environment(F.Remove(Env.SubExprBindings, E), Env.BlkExprBindings);
-  }
-  
-  Environment AddBlkExpr(const Environment& Env, const Stmt *E, SVal V) {
-    return Environment(Env.SubExprBindings, F.Add(Env.BlkExprBindings, E, V));
-  }
-  
-  Environment AddSubExpr(const Environment& Env, const Stmt *E, SVal V) {
-    return Environment(F.Add(Env.SubExprBindings, E, V), Env.BlkExprBindings);
-  }
-  
-  /// RemoveSubExprBindings - Return a new environment object with
-  ///  the same bindings as the provided environment except with all the
-  ///  subexpression bindings removed.
-  Environment RemoveSubExprBindings(const Environment& Env) {
-    return Environment(F.GetEmptyMap(), Env.BlkExprBindings);
-  }
   
   Environment getInitialEnvironment() {
-    return Environment(F.GetEmptyMap(), F.GetEmptyMap());
+    return Environment(F.GetEmptyMap());
   }
   
-  Environment BindExpr(const Environment& Env, const Stmt* E, SVal V,
-                       bool isBlkExpr, bool Invalidate);
-
-  Environment
-  RemoveDeadBindings(Environment Env, Stmt* Loc, SymbolReaper& SymReaper,
-                     GRStateManager& StateMgr, const GRState *state,
-                     llvm::SmallVectorImpl<const MemRegion*>& DRoots);
+  Environment BindExpr(Environment Env, const Stmt *S, SVal V,
+                       bool Invalidate);
 
+  Environment RemoveDeadBindings(Environment Env, const Stmt *S,
+                                 SymbolReaper &SymReaper, const GRState *ST,
+                          llvm::SmallVectorImpl<const MemRegion*>& RegionRoots);
 };
   
 } // end clang namespace
index 7425d1f4bc90d3822c13fceab76aaa2c1958cda2..94ef54b731e5e43809bb7f4126d36abe5ea750e3 100644 (file)
@@ -67,6 +67,15 @@ template <typename T> struct GRStateTrait {
 
 class GRStateManager;
   
+class GRStateContext : public std::pair<GRStateManager*, AnalysisContext*> {
+public:
+  GRStateContext(GRStateManager *Mgr, AnalysisContext *ACtx)
+    : std::pair<GRStateManager*, AnalysisContext*>(Mgr, ACtx) {}
+  
+  GRStateManager *getStateManager() const { return first; }
+  AnalysisContext *getAnalysisContext() const { return second; }
+};
+  
 /// GRState - This class encapsulates the actual data values for
 ///  for a "state" in our symbolic value tracking.  It is intended to be
 ///  used as a functional object; that is once it is created and made
@@ -81,7 +90,7 @@ private:
   
   friend class GRStateManager;
 
-  GRStateManager *Mgr;
+  GRStateContext StateCtx;
   Environment Env;
   Store St;
 
@@ -92,9 +101,9 @@ public:
 public:
   
   /// This ctor is used when creating the first GRState object.
-  GRState(GRStateManager *mgr, const Environment& env,  Store st,
-          GenericDataMap gdm)
-    : Mgr(mgr),
+  GRState(GRStateManager *mgr, AnalysisContext *actx, const Environment& env,
+          Store st, GenericDataMap gdm)
+    : StateCtx(mgr, actx),
       Env(env),
       St(st),
       GDM(gdm) {}
@@ -103,13 +112,21 @@ public:
   ///  in FoldingSetNode will also get copied.
   GRState(const GRState& RHS)
     : llvm::FoldingSetNode(),
-      Mgr(RHS.Mgr),
+      StateCtx(RHS.StateCtx),
       Env(RHS.Env),
       St(RHS.St),
       GDM(RHS.GDM) {}
   
   /// getStateManager - Return the GRStateManager associated with this state.
-  GRStateManager &getStateManager() const { return *Mgr; }
+  GRStateManager &getStateManager() const {
+    return *StateCtx.getStateManager();
+  }
+  
+  /// getAnalysisContext - Return the AnalysisContext associated with this
+  /// state.
+  AnalysisContext &getAnalysisContext() const {
+    return *StateCtx.getAnalysisContext();
+  }
   
   /// getEnvironment - Return the environment associated with this state.
   ///  The environment is the mapping from expressions to values.
@@ -129,6 +146,7 @@ public:
   /// Profile - Profile the contents of a GRState object for use
   ///  in a FoldingSet.
   static void Profile(llvm::FoldingSetNodeID& ID, const GRState* V) {
+    // FIXME: Do we need to include the AnalysisContext in the profile?
     V->Env.Profile(ID);
     ID.AddPointer(V->St);
     V->GDM.Profile(ID);
@@ -147,16 +165,7 @@ public:
   /// makeWithStore - Return a GRState with the same values as the current
   /// state with the exception of using the specified Store.
   const GRState *makeWithStore(Store store) const;
-  
-  // Iterators.
-  typedef Environment::seb_iterator seb_iterator;
-  seb_iterator seb_begin() const { return Env.seb_begin(); }
-  seb_iterator seb_end() const { return Env.beb_end(); }
-  
-  typedef Environment::beb_iterator beb_iterator;
-  beb_iterator beb_begin() const { return Env.beb_begin(); }
-  beb_iterator beb_end() const { return Env.beb_end(); }
-  
+    
   BasicValueFactory &getBasicVals() const;
   SymbolManager &getSymbolManager() const;
   GRTransferFuncs &getTransferFuncs() const;
@@ -216,16 +225,8 @@ public:
   const GRState* bindCompoundLiteral(const CompoundLiteralExpr* CL,
                                      SVal V) const;
   
-  const GRState *bindExpr(const Stmt* Ex, SVal V, bool isBlkExpr,
-                          bool Invalidate) const;
-  
-  const GRState *bindExpr(const Stmt* Ex, SVal V, CFG &cfg, 
-                          bool Invalidate = true) const;
-  
-  const GRState *bindBlkExpr(const Stmt *Ex, SVal V) const {
-    return bindExpr(Ex, V, true, false);
-  }
-  
+  const GRState *bindExpr(const Stmt *S, SVal V, bool Invalidate = true) const;
+    
   const GRState *bindDecl(const VarDecl *VD, const LocationContext *LC,
                           SVal V) const;
   
@@ -259,8 +260,6 @@ public:
 
   SVal getSVal(const Stmt* Ex) const;
   
-  SVal getBlkExprSVal(const Stmt* Ex) const;
-  
   SVal getSValAsScalarOrLoc(const Stmt *Ex) const;
   
   SVal getSVal(Loc LV, QualType T = QualType()) const;
@@ -475,12 +474,6 @@ public:
   const GRState* RemoveDeadBindings(const GRState* St, Stmt* Loc, 
                                     SymbolReaper& SymReaper);
 
-  const GRState* RemoveSubExprBindings(const GRState* St) {
-    GRState NewSt = *St;
-    NewSt.Env = EnvMgr.RemoveSubExprBindings(NewSt.Env);
-    return getPersistentState(NewSt);
-  }
-  
 public:
 
   SVal ArrayToPointer(Loc Array) {
@@ -583,36 +576,36 @@ public:
 
 inline const VarRegion* GRState::getRegion(const VarDecl *D,
                                            const LocationContext *LC) const {
-  return Mgr->getRegionManager().getVarRegion(D, LC);
+  return getStateManager().getRegionManager().getVarRegion(D, LC);
 }
 
 inline const GRState *GRState::assume(SVal Cond, bool Assumption) const {
-  return Mgr->ConstraintMgr->Assume(this, Cond, Assumption);
+  return getStateManager().ConstraintMgr->Assume(this, Cond, Assumption);
 }
 
 inline const GRState *GRState::assumeInBound(SVal Idx, SVal UpperBound,
                                              bool Assumption) const {
-  return Mgr->ConstraintMgr->AssumeInBound(this, Idx, UpperBound, Assumption);
+  return getStateManager().ConstraintMgr->AssumeInBound(this, Idx, UpperBound, Assumption);
 } 
 
 inline const GRState *GRState::bindCompoundLiteral(const CompoundLiteralExpr* CL,
                                             SVal V) const {
-  return Mgr->StoreMgr->BindCompoundLiteral(this, CL, V);
+  return getStateManager().StoreMgr->BindCompoundLiteral(this, CL, V);
 }
   
 inline const GRState *GRState::bindDecl(const VarDecl* VD,
                                         const LocationContext *LC,
                                         SVal IVal) const {
-  return Mgr->StoreMgr->BindDecl(this, VD, LC, IVal);
+  return getStateManager().StoreMgr->BindDecl(this, VD, LC, IVal);
 }
 
 inline const GRState *GRState::bindDeclWithNoInit(const VarDecl* VD,
                                                   const LocationContext *LC) const {
-  return Mgr->StoreMgr->BindDeclWithNoInit(this, VD, LC);
+  return getStateManager().StoreMgr->BindDeclWithNoInit(this, VD, LC);
 }
   
 inline const GRState *GRState::bindLoc(Loc LV, SVal V) const {
-  return Mgr->StoreMgr->Bind(this, LV, V);
+  return getStateManager().StoreMgr->Bind(this, LV, V);
 }
 
 inline const GRState *GRState::bindLoc(SVal LV, SVal V) const {
@@ -621,39 +614,35 @@ inline const GRState *GRState::bindLoc(SVal LV, SVal V) const {
   
 inline SVal GRState::getLValue(const VarDecl* VD,
                                const LocationContext *LC) const {
-  return Mgr->StoreMgr->getLValueVar(this, VD, LC);
+  return getStateManager().StoreMgr->getLValueVar(this, VD, LC);
 }
 
 inline SVal GRState::getLValue(const StringLiteral *literal) const {
-  return Mgr->StoreMgr->getLValueString(this, literal);
+  return getStateManager().StoreMgr->getLValueString(this, literal);
 }
   
 inline SVal GRState::getLValue(const CompoundLiteralExpr *literal) const {
-  return Mgr->StoreMgr->getLValueCompoundLiteral(this, literal);
+  return getStateManager().StoreMgr->getLValueCompoundLiteral(this, literal);
 }
 
 inline SVal GRState::getLValue(const ObjCIvarDecl *D, SVal Base) const {
-  return Mgr->StoreMgr->getLValueIvar(this, D, Base);
+  return getStateManager().StoreMgr->getLValueIvar(this, D, Base);
 }
   
 inline SVal GRState::getLValue(SVal Base, const FieldDecl* D) const {
-  return Mgr->StoreMgr->getLValueField(this, Base, D);
+  return getStateManager().StoreMgr->getLValueField(this, Base, D);
 }
   
 inline SVal GRState::getLValue(QualType ElementType, SVal Base, SVal Idx) const{
-  return Mgr->StoreMgr->getLValueElement(this, ElementType, Base, Idx);
+  return getStateManager().StoreMgr->getLValueElement(this, ElementType, Base, Idx);
 }
   
 inline const llvm::APSInt *GRState::getSymVal(SymbolRef sym) const {
-  return Mgr->getSymVal(this, sym);
+  return getStateManager().getSymVal(this, sym);
 }
   
 inline SVal GRState::getSVal(const Stmt* Ex) const {
-  return Env.GetSVal(Ex, Mgr->ValueMgr);
-}
-
-inline SVal GRState::getBlkExprSVal(const Stmt* Ex) const {  
-  return Env.GetBlkExprSVal(Ex, Mgr->ValueMgr);
+  return Env.GetSVal(Ex, getStateManager().ValueMgr);
 }
 
 inline SVal GRState::getSValAsScalarOrLoc(const Stmt *S) const {
@@ -667,62 +656,62 @@ inline SVal GRState::getSValAsScalarOrLoc(const Stmt *S) const {
 }
 
 inline SVal GRState::getSVal(Loc LV, QualType T) const {
-  return Mgr->StoreMgr->Retrieve(this, LV, T).getSVal();
+  return getStateManager().StoreMgr->Retrieve(this, LV, T).getSVal();
 }
 
 inline SVal GRState::getSVal(const MemRegion* R) const {
-  return Mgr->StoreMgr->Retrieve(this, loc::MemRegionVal(R)).getSVal();
+  return getStateManager().StoreMgr->Retrieve(this, loc::MemRegionVal(R)).getSVal();
 }
   
 inline BasicValueFactory &GRState::getBasicVals() const {
-  return Mgr->getBasicVals();
+  return getStateManager().getBasicVals();
 }
 
 inline SymbolManager &GRState::getSymbolManager() const {
-  return Mgr->getSymbolManager();
+  return getStateManager().getSymbolManager();
 }
   
 inline GRTransferFuncs &GRState::getTransferFuncs() const {
-  return Mgr->getTransferFuncs();
+  return getStateManager().getTransferFuncs();
 }
 
 template<typename T>
 const GRState *GRState::add(typename GRStateTrait<T>::key_type K) const {
-  return Mgr->add<T>(this, K, get_context<T>());
+  return getStateManager().add<T>(this, K, get_context<T>());
 }
   
 template <typename T>
 typename GRStateTrait<T>::context_type GRState::get_context() const {
-  return Mgr->get_context<T>();
+  return getStateManager().get_context<T>();
 }
   
 template<typename T>
 const GRState *GRState::remove(typename GRStateTrait<T>::key_type K) const {
-  return Mgr->remove<T>(this, K, get_context<T>());
+  return getStateManager().remove<T>(this, K, get_context<T>());
 }
 
 template<typename T>
 const GRState *GRState::remove(typename GRStateTrait<T>::key_type K,
                                typename GRStateTrait<T>::context_type C) const {
-  return Mgr->remove<T>(this, K, C);
+  return getStateManager().remove<T>(this, K, C);
 }
   
 template<typename T>
 const GRState *GRState::set(typename GRStateTrait<T>::data_type D) const {
-  return Mgr->set<T>(this, D);
+  return getStateManager().set<T>(this, D);
 }
   
 template<typename T>
 const GRState *GRState::set(typename GRStateTrait<T>::key_type K,
                             typename GRStateTrait<T>::value_type E) const {
-  return Mgr->set<T>(this, K, E, get_context<T>());
+  return getStateManager().set<T>(this, K, E, get_context<T>());
 }
   
 template<typename T>
 const GRState *GRState::set(typename GRStateTrait<T>::key_type K,
                             typename GRStateTrait<T>::value_type E,
                             typename GRStateTrait<T>::context_type C) const {
-  return Mgr->set<T>(this, K, E, C);
+  return getStateManager().set<T>(this, K, E, C);
 }
   
 template <typename CB>
index 32ac27f258dded4cfaa111d9601052036cd88138..9216e1ea01701c9381710a2b643cecc59d359c48 100644 (file)
@@ -2900,7 +2900,7 @@ void CFRefCount::EvalSummary(ExplodedNodeSet& Dst,
         unsigned Count = Builder.getCurrentBlockCount();
         ValueManager &ValMgr = Eng.getValueManager();
         SVal X = ValMgr.getConjuredSymbolVal(Ex, T, Count);
-        state = state->bindExpr(Ex, X, Pred->getCFG(), false);
+        state = state->bindExpr(Ex, X, false);
       }      
       
       break;
@@ -2911,14 +2911,14 @@ void CFRefCount::EvalSummary(ExplodedNodeSet& Dst,
       assert (arg_end >= arg_beg);
       assert (idx < (unsigned) (arg_end - arg_beg));
       SVal V = state->getSValAsScalarOrLoc(*(arg_beg+idx));
-      state = state->bindExpr(Ex, V, Pred->getCFG(), false);
+      state = state->bindExpr(Ex, V, false);
       break;
     }
       
     case RetEffect::ReceiverAlias: {
       assert (Receiver);
       SVal V = state->getSValAsScalarOrLoc(Receiver);
-      state = state->bindExpr(Ex, V, Pred->getCFG(), false);
+      state = state->bindExpr(Ex, V, false);
       break;
     }
       
@@ -2930,7 +2930,7 @@ void CFRefCount::EvalSummary(ExplodedNodeSet& Dst,
       QualType RetT = GetReturnType(Ex, ValMgr.getContext());      
       state = state->set<RefBindings>(Sym, RefVal::makeOwned(RE.getObjKind(),
                                                             RetT));
-      state = state->bindExpr(Ex, ValMgr.makeLoc(Sym), Pred->getCFG(), false);
+      state = state->bindExpr(Ex, ValMgr.makeLoc(Sym), false);
 
       // FIXME: Add a flag to the checker where allocations are assumed to
       // *not fail.
@@ -2953,7 +2953,7 @@ void CFRefCount::EvalSummary(ExplodedNodeSet& Dst,
       QualType RetT = GetReturnType(Ex, ValMgr.getContext());      
       state = state->set<RefBindings>(Sym, RefVal::makeNotOwned(RE.getObjKind(),
                                                                RetT));
-      state = state->bindExpr(Ex, ValMgr.makeLoc(Sym), Pred->getCFG(), false);
+      state = state->bindExpr(Ex, ValMgr.makeLoc(Sym), false);
       break;
     }
   }
index 9d8e09c7041aac2a40f13ac614db1c5380e2d3c3..98cd7d816882b84e1c16a33617118e830c00de54 100644 (file)
@@ -68,42 +68,18 @@ SVal Environment::GetSVal(const Stmt *E, ValueManager& ValMgr) const {
   return LookupExpr(E);
 }
 
-SVal Environment::GetBlkExprSVal(const Stmt *E, ValueManager& ValMgr) const {
-  
-  while (1) {
-    switch (E->getStmtClass()) {
-      case Stmt::ParenExprClass:
-        E = cast<ParenExpr>(E)->getSubExpr();
-        continue;
-        
-      case Stmt::CharacterLiteralClass: {
-        const CharacterLiteral* C = cast<CharacterLiteral>(E);
-        return ValMgr.makeIntVal(C->getValue(), C->getType());
-      }
-        
-      case Stmt::IntegerLiteralClass: {
-        return ValMgr.makeIntVal(cast<IntegerLiteral>(E));
-      }
-        
-      default:
-        return LookupBlkExpr(E);
-    }
-  }
-}
-
-Environment EnvironmentManager::BindExpr(const Environment& Env, const Stmt* E,
-                                         SVal V, bool isBlkExpr,
-                                         bool Invalidate) {  
-  assert (E);
+Environment EnvironmentManager::BindExpr(Environment Env, const Stmt *S,
+                                         SVal V, bool Invalidate) {  
+  assert(S);
   
   if (V.isUnknown()) {    
     if (Invalidate)
-      return isBlkExpr ? RemoveBlkExpr(Env, E) : RemoveSubExpr(Env, E);
+      return Environment(F.Remove(Env.ExprBindings, S));
     else
       return Env;
   }
 
-  return isBlkExpr ? AddBlkExpr(Env, E, V) : AddSubExpr(Env, E, V);
+  return Environment(F.Add(Env.ExprBindings, S, V));
 }
 
 namespace {
@@ -124,23 +100,34 @@ public:
 //   - Mark the region in DRoots if the binding is a loc::MemRegionVal.
 
 Environment 
-EnvironmentManager::RemoveDeadBindings(Environment Env, Stmt* Loc,
-                                       SymbolReaper& SymReaper,
-                                       GRStateManager& StateMgr,
-                                       const GRState *state,
-                              llvm::SmallVectorImpl<const MemRegion*>& DRoots) {
+EnvironmentManager::RemoveDeadBindings(Environment Env, const Stmt *S,
+                                       SymbolReaper &SymReaper,
+                                       const GRState *ST,
+                              llvm::SmallVectorImpl<const MemRegion*> &DRoots) {
+  
+  CFG &C = *ST->getAnalysisContext().getCFG();
+  
+  // We construct a new Environment object entirely, as this is cheaper than
+  // individually removing all the subexpression bindings (which will greatly
+  // outnumber block-level expression bindings).
+  Environment NewEnv = getInitialEnvironment();
   
-  // Drop bindings for subexpressions.
-  Env = RemoveSubExprBindings(Env);
-
   // Iterate over the block-expr bindings.
-  for (Environment::beb_iterator I = Env.beb_begin(), E = Env.beb_end(); 
+  for (Environment::iterator I = Env.begin(), E = Env.end(); 
        I != E; ++I) {
+    
     const Stmt *BlkExpr = I.getKey();
-
-    if (SymReaper.isLive(Loc, BlkExpr)) {
-      SVal X = I.getData();
-
+    
+    // Not a block-level expression?
+    if (!C.isBlkExpr(BlkExpr))
+      continue;
+    
+    const SVal &X = I.getData();
+        
+    if (SymReaper.isLive(S, BlkExpr)) {
+      // Copy the binding to the new map.
+      NewEnv.ExprBindings = F.Add(NewEnv.ExprBindings, BlkExpr, X);
+      
       // If the block expr's value is a memory region, then mark that region.
       if (isa<loc::MemRegionVal>(X)) {
         const MemRegion* R = cast<loc::MemRegionVal>(X).getRegion();
@@ -151,28 +138,23 @@ EnvironmentManager::RemoveDeadBindings(Environment Env, Stmt* Loc,
         // We only add one level super region for now.
 
         // FIXME: maybe multiple level of super regions should be added.
-        if (const SubRegion *SR = dyn_cast<SubRegion>(R)) {
+        if (const SubRegion *SR = dyn_cast<SubRegion>(R))
           DRoots.push_back(SR->getSuperRegion());
-        }
       }
 
       // Mark all symbols in the block expr's value live.
       MarkLiveCallback cb(SymReaper);
-      state->scanReachableSymbols(X, cb);
-    } else {
-      // The block expr is dead.
-      SVal X = I.getData();
-
-      // Do not misclean LogicalExpr or ConditionalOperator.  It is dead at the
-      // beginning of itself, but we need its UndefinedVal to determine its
-      // SVal.
-
-      if (X.isUndef() && cast<UndefinedVal>(X).getData())
-        continue;
-
-      Env = RemoveBlkExpr(Env, BlkExpr);
+      ST->scanReachableSymbols(X, cb);
+      continue;
     }
+
+    // Otherwise the expression is dead with a couple exceptions.
+    // Do not misclean LogicalExpr or ConditionalOperator.  It is dead at the
+    // beginning of itself, but we need its UndefinedVal to determine its
+    // SVal.
+    if (X.isUndef() && cast<UndefinedVal>(X).getData())
+      NewEnv.ExprBindings = F.Add(NewEnv.ExprBindings, BlkExpr, X);
   }
 
-  return Env;
+  return NewEnv;
 }
index 600c52c5b09e934643b52a3692ffdc479baf97d9..41caeaf68a9fd116d017c72d69ffaf2191386f22 100644 (file)
@@ -341,8 +341,7 @@ void GRExprEngine::Visit(Stmt* S, ExplodedNode* Pred, ExplodedNodeSet& Dst) {
       }
       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 @@ void GRExprEngine::Visit(Stmt* S, ExplodedNode* Pred, ExplodedNodeSet& Dst) {
                
       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 @@ void GRExprEngine::VisitLValue(Expr* Ex, ExplodedNode* Pred,
     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 @@ const GRState* GRExprEngine::MarkBranch(const GRState* state,
                  (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 @@ const GRState* GRExprEngine::MarkBranch(const GRState* state,
       else
         Ex = C->getRHS();
       
-      return state->bindBlkExpr(C, UndefinedVal(Ex));
+      return state->bindExpr(C, UndefinedVal(Ex));
     }
       
     case Stmt::ChooseExprClass: { // ?:
@@ -637,7 +635,7 @@ const GRState* GRExprEngine::MarkBranch(const GRState* state,
       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 @@ static SVal RecoverCastedSymbol(GRStateManager& StateMgr, const GRState* state,
 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 @@ void GRExprEngine::ProcessBranch(Stmt* Condition, Stmt* Term,
   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 @@ void GRExprEngine::VisitGuardedExpr(Expr* Ex, Expr* L, Expr* R,
   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 @@ void GRExprEngine::VisitLogicalExpr(BinaryOperator* B, ExplodedNode* Pred,
   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 @@ void GRExprEngine::VisitLogicalExpr(BinaryOperator* B, ExplodedNode* Pred,
   
   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 @@ void GRExprEngine::VisitLogicalExpr(BinaryOperator* B, ExplodedNode* Pred,
     // 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 @@ void GRExprEngine::VisitLogicalExpr(BinaryOperator* B, ExplodedNode* Pred,
     // 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 @@ void GRExprEngine::VisitDeclRefExpr(DeclRefExpr *Ex, ExplodedNode *Pred,
     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 @@ void GRExprEngine::VisitDeclRefExpr(DeclRefExpr *Ex, ExplodedNode *Pred,
     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 @@ void GRExprEngine::VisitArraySubscriptExpr(ArraySubscriptExpr* A,
                                 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 @@ void GRExprEngine::VisitMemberExpr(MemberExpr* M, ExplodedNode* Pred,
     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 @@ void GRExprEngine::EvalLoad(ExplodedNodeSet& Dst, Expr* Ex, ExplodedNode* Pred,
 
   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 @@ void GRExprEngine::EvalLoad(ExplodedNodeSet& Dst, Expr* Ex, ExplodedNode* Pred,
     //  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 @@ static bool EvalOSAtomicCompareAndSwap(ExplodedNodeSet& Dst,
         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 @@ void GRExprEngine::VisitCallRec(CallExpr* CE, ExplodedNode* Pred,
             // 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 @@ void GRExprEngine::VisitCallRec(CallExpr* CE, ExplodedNode* Pred,
             // 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 @@ void GRExprEngine::EvalEagerlyAssume(ExplodedNodeSet &Dst, ExplodedNodeSet &Src,
       // 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 @@ void GRExprEngine::EvalEagerlyAssume(ExplodedNodeSet &Dst, ExplodedNodeSet &Src,
       // 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 @@ void GRExprEngine::VisitObjCIvarRefExpr(ObjCIvarRefExpr* Ex,
     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 @@ void GRExprEngine::VisitObjCForCollectionStmtAux(ObjCForCollectionStmt* S,
 
   // 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 @@ void GRExprEngine::VisitObjCMessageExprDispatchHelper(ObjCMessageExpr* ME,
               // 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 @@ void GRExprEngine::VisitCast(Expr* CastE, Expr* Ex, ExplodedNode* Pred, Exploded
     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 @@ void GRExprEngine::VisitCompoundLiteralExpr(CompoundLiteralExpr* CL,
     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 @@ void GRExprEngine::VisitInitListExpr(InitListExpr* E, ExplodedNode* Pred,
     // 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 @@ void GRExprEngine::VisitInitListExpr(InitListExpr* E, ExplodedNode* Pred,
           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 @@ void GRExprEngine::VisitInitListExpr(InitListExpr* E, ExplodedNode* Pred,
     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 @@ void GRExprEngine::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr* Ex,
     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 @@ void GRExprEngine::VisitUnaryOperator(UnaryOperator* U, ExplodedNode* Pred,
         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 @@ void GRExprEngine::VisitUnaryOperator(UnaryOperator* U, ExplodedNode* Pred,
         // 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 @@ void GRExprEngine::VisitUnaryOperator(UnaryOperator* U, ExplodedNode* Pred,
         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 @@ void GRExprEngine::VisitUnaryOperator(UnaryOperator* U, ExplodedNode* Pred,
       
       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 @@ void GRExprEngine::VisitUnaryOperator(UnaryOperator* U, ExplodedNode* Pred,
       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 @@ void GRExprEngine::VisitUnaryOperator(UnaryOperator* U, ExplodedNode* Pred,
         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 @@ void GRExprEngine::VisitUnaryOperator(UnaryOperator* U, ExplodedNode* Pred,
             
           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 @@ void GRExprEngine::VisitUnaryOperator(UnaryOperator* U, ExplodedNode* Pred,
                                  U->getType());
             }
             
-            state = state->bindExpr(U, Result, (*I)->getCFG());
+            state = state->bindExpr(U, Result);
             
             break;
         }
@@ -2576,7 +2562,7 @@ void GRExprEngine::VisitUnaryOperator(UnaryOperator* U, ExplodedNode* Pred,
         
       // 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 @@ void GRExprEngine::VisitUnaryOperator(UnaryOperator* U, ExplodedNode* Pred,
         }        
       }
       
-      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 @@ void GRExprEngine::VisitBinaryOperator(BinaryOperator* B,
           
           // 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 @@ void GRExprEngine::VisitBinaryOperator(BinaryOperator* B,
             // 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 @@ void GRExprEngine::VisitBinaryOperator(BinaryOperator* B,
           
           // 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 @@ void GRExprEngine::VisitBinaryOperator(BinaryOperator* B,
         
         // 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 @@ void GRExprEngine::VisitBinaryOperator(BinaryOperator* B,
         // 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 @@ void GRExprEngine::VisitBinaryOperator(BinaryOperator* B,
           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);
       }
     }
index 862bd5f72d53b6b436a751ace12b9449c38a8640..7bef351006233d0df433035bc6dfa413f3199e02 100644 (file)
@@ -46,7 +46,7 @@ GRStateManager::RemoveDeadBindings(const GRState* state, Stmt* Loc,
   llvm::SmallVector<const MemRegion*, 10> RegionRoots;
   GRState NewState = *state;
 
-  NewState.Env = EnvMgr.RemoveDeadBindings(NewState.Env, Loc, SymReaper, *this,
+  NewState.Env = EnvMgr.RemoveDeadBindings(NewState.Env, Loc, SymReaper,
                                            state, RegionRoots);
 
   // Clean up the store.
@@ -58,14 +58,14 @@ GRStateManager::RemoveDeadBindings(const GRState* state, Stmt* Loc,
 
 const GRState *GRState::unbindLoc(Loc LV) const {
   Store OldStore = getStore();
-  Store NewStore = Mgr->StoreMgr->Remove(OldStore, LV);
+  Store NewStore = getStateManager().StoreMgr->Remove(OldStore, LV);
   
   if (NewStore == OldStore)
     return this;
   
   GRState NewSt = *this;
   NewSt.St = NewStore;
-  return Mgr->getPersistentState(NewSt);    
+  return getStateManager().getPersistentState(NewSt);    
 }
 
 SVal GRState::getSValAsScalarOrLoc(const MemRegion *R) const {
@@ -76,7 +76,7 @@ SVal GRState::getSValAsScalarOrLoc(const MemRegion *R) const {
     return UnknownVal();
 
   if (const TypedRegion *TR = dyn_cast<TypedRegion>(R)) {
-    QualType T = TR->getValueType(Mgr->getContext());
+    QualType T = TR->getValueType(getStateManager().getContext());
     if (Loc::IsLocType(T) || T->isIntegerType())
       return getSVal(R);
   }
@@ -85,38 +85,22 @@ SVal GRState::getSValAsScalarOrLoc(const MemRegion *R) const {
 }
 
 
-const GRState *GRState::bindExpr(const Stmt* Ex, SVal V, bool isBlkExpr,
-                                 bool Invalidate) const {
+const GRState *GRState::bindExpr(const Stmt* Ex, SVal V, bool Invalidate) const {
   
-  Environment NewEnv = Mgr->EnvMgr.BindExpr(Env, Ex, V, isBlkExpr, Invalidate);
+  Environment NewEnv = getStateManager().EnvMgr.BindExpr(Env, Ex, V,
+                                                         Invalidate);
   
   if (NewEnv == Env)
     return this;
   
   GRState NewSt = *this;
   NewSt.Env = NewEnv;
-  return Mgr->getPersistentState(NewSt);
-}
-
-const GRState *GRState::bindExpr(const Stmt* Ex, SVal V, CFG &cfg,
-                                 bool Invalidate) const {
-  
-  bool isBlkExpr = false;
-  
-  if (Ex == Mgr->CurrentStmt) {
-      // FIXME: Should this just be an assertion?  When would we want to set
-      // the value of a block-level expression if it wasn't CurrentStmt?
-    isBlkExpr = cfg.isBlkExpr(Ex);
-    
-    if (!isBlkExpr)
-      return this;
-  }
-  
-  return bindExpr(Ex, V, isBlkExpr, Invalidate);
+  return getStateManager().getPersistentState(NewSt);
 }
 
 const GRState* GRStateManager::getInitialState(const LocationContext *InitLoc) {
-  GRState State(this, EnvMgr.getInitialEnvironment(), 
+  GRState State(this, InitLoc->getAnalysisContext(),
+                EnvMgr.getInitialEnvironment(), 
                 StoreMgr->getInitialStore(InitLoc),
                 GDMFactory.GetEmptyMap());
 
@@ -141,7 +125,7 @@ const GRState* GRStateManager::getPersistentState(GRState& State) {
 const GRState* GRState::makeWithStore(Store store) const {
   GRState NewSt = *this;
   NewSt.St = store;
-  return Mgr->getPersistentState(NewSt);
+  return getStateManager().getPersistentState(NewSt);
 }
 
 //===----------------------------------------------------------------------===//
@@ -151,12 +135,17 @@ const GRState* GRState::makeWithStore(Store store) const {
 void GRState::print(llvm::raw_ostream& Out, const char* nl,
                     const char* sep) const {  
   // Print the store.
-  Mgr->getStoreManager().print(getStore(), Out, nl, sep);
+  GRStateManager &Mgr = getStateManager();
+  Mgr.getStoreManager().print(getStore(), Out, nl, sep);
+  
+  CFG &C = *getAnalysisContext().getCFG();
   
   // Print Subexpression bindings.
   bool isFirst = true;
   
-  for (seb_iterator I = seb_begin(), E = seb_end(); I != E; ++I) {        
+  for (Environment::iterator I = Env.begin(), E = Env.end(); I != E; ++I) {    
+    if (C.isBlkExpr(I.getKey()))
+      continue;
     
     if (isFirst) {
       Out << nl << nl << "Sub-Expressions:" << nl;
@@ -172,8 +161,10 @@ void GRState::print(llvm::raw_ostream& Out, const char* nl,
   
   // Print block-expression bindings.
   isFirst = true;
-  
-  for (beb_iterator I = beb_begin(), E = beb_end(); I != E; ++I) {      
+
+  for (Environment::iterator I = Env.begin(), E = Env.end(); I != E; ++I) {
+    if (!C.isBlkExpr(I.getKey()))
+      continue;
 
     if (isFirst) {
       Out << nl << nl << "Block-level Expressions:" << nl;
@@ -187,11 +178,11 @@ void GRState::print(llvm::raw_ostream& Out, const char* nl,
     Out << " : " << I.getData();
   }
   
-  Mgr->getConstraintManager().print(this, Out, nl, sep);
+  Mgr.getConstraintManager().print(this, Out, nl, sep);
   
   // Print checker-specific data.
-  for (std::vector<Printer*>::iterator I = Mgr->Printers.begin(),
-                                       E = Mgr->Printers.end(); I != E; ++I) {
+  for (std::vector<Printer*>::iterator I = Mgr.Printers.begin(),
+                                       E = Mgr.Printers.end(); I != E; ++I) {
     (*I)->Print(Out, this, nl, sep);
   }
 }