diff options
-rw-r--r-- | include/clang/Analysis/PathSensitive/Environment.h | 88 | ||||
-rw-r--r-- | include/clang/Analysis/PathSensitive/GRState.h | 119 | ||||
-rw-r--r-- | lib/Analysis/CFRefCount.cpp | 10 | ||||
-rw-r--r-- | lib/Analysis/Environment.cpp | 98 | ||||
-rw-r--r-- | lib/Analysis/GRExprEngine.cpp | 136 | ||||
-rw-r--r-- | lib/Analysis/GRState.cpp | 59 |
6 files changed, 204 insertions, 306 deletions
diff --git a/include/clang/Analysis/PathSensitive/Environment.h b/include/clang/Analysis/PathSensitive/Environment.h index 6f8a126427..f4d36c3550 100644 --- a/include/clang/Analysis/PathSensitive/Environment.h +++ b/include/clang/Analysis/PathSensitive/Environment.h @@ -26,10 +26,12 @@ 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 diff --git a/include/clang/Analysis/PathSensitive/GRState.h b/include/clang/Analysis/PathSensitive/GRState.h index 7425d1f4bc..94ef54b731 100644 --- a/include/clang/Analysis/PathSensitive/GRState.h +++ b/include/clang/Analysis/PathSensitive/GRState.h @@ -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> diff --git a/lib/Analysis/CFRefCount.cpp b/lib/Analysis/CFRefCount.cpp index 32ac27f258..9216e1ea01 100644 --- a/lib/Analysis/CFRefCount.cpp +++ b/lib/Analysis/CFRefCount.cpp @@ -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; } } diff --git a/lib/Analysis/Environment.cpp b/lib/Analysis/Environment.cpp index 9d8e09c704..98cd7d8168 100644 --- a/lib/Analysis/Environment.cpp +++ b/lib/Analysis/Environment.cpp @@ -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; } diff --git a/lib/Analysis/GRExprEngine.cpp b/lib/Analysis/GRExprEngine.cpp index 600c52c5b0..41caeaf68a 100644 --- a/lib/Analysis/GRExprEngine.cpp +++ b/lib/Analysis/GRExprEngine.cpp @@ -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()); + con |