From: Ted Kremenek Date: Sat, 19 Feb 2011 01:59:33 +0000 (+0000) Subject: Add 'StoreRef' smart pointer to allow more fine-grain memory lifetime control of... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=77a4d5687c2cb3199c689892c9d040a94ff270af;p=clang Add 'StoreRef' smart pointer to allow more fine-grain memory lifetime control of Store objects. This yields a minor memory reduction (for larger functions) on Sqlite at the cost of slightly higher memory usage on some functions because of the increased size of GRState (which can be optimized). I expect the real memory savings from this enhancement will come when we aggressively canabilize more of the ExplodedGraph. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@126012 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/GRState.h b/include/clang/StaticAnalyzer/Core/PathSensitive/GRState.h index 80a89e0b78..92156d508f 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/GRState.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/GRState.h @@ -83,19 +83,19 @@ private: GRStateManager *stateMgr; Environment Env; // Maps a Stmt to its current SVal. - Store St; // Maps a location to its current value. + StoreRef St; // Maps a location to its current value. GenericDataMap GDM; // Custom data stored by a client of this class. unsigned refCount; /// 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; + const GRState *makeWithStore(const StoreRef &store) const; public: /// This ctor is used when creating the first GRState object. GRState(GRStateManager *mgr, const Environment& env, - Store st, GenericDataMap gdm) + StoreRef st, GenericDataMap gdm) : stateMgr(mgr), Env(env), St(st), @@ -122,12 +122,14 @@ public: /// The environment is the mapping from expressions to values. const Environment& getEnvironment() const { return Env; } + /// getStore - Return the store associated with this state. The store /// is a mapping from locations to values. - Store getStore() const { return St; } - + Store getStore() const { return St.getStore(); } +#if 0 void setStore(Store s) { St = s; } - +#endif + /// getGDM - Return the generic data map associated with this state. GenericDataMap getGDM() const { return GDM; } @@ -138,7 +140,7 @@ public: /// have the same Environment, Store, and GenericDataMap. static void Profile(llvm::FoldingSetNodeID& ID, const GRState* V) { V->Env.Profile(ID); - ID.AddPointer(V->St); + ID.AddPointer(V->St.getStore()); V->GDM.Profile(ID); } @@ -713,11 +715,11 @@ inline SVal GRState::getSValAsScalarOrLoc(const Stmt *S) const { } inline SVal GRState::getRawSVal(Loc LV, QualType T) const { - return getStateManager().StoreMgr->Retrieve(St, LV, T); + return getStateManager().StoreMgr->Retrieve(getStore(), LV, T); } inline SVal GRState::getSVal(const MemRegion* R) const { - return getStateManager().StoreMgr->Retrieve(St, loc::MemRegionVal(R)); + return getStateManager().StoreMgr->Retrieve(getStore(), loc::MemRegionVal(R)); } inline BasicValueFactory &GRState::getBasicVals() const { diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h b/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h index 24341d1f2e..0251311c27 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h @@ -37,7 +37,27 @@ typedef const void* Store; class GRState; class GRStateManager; class SubRegionMap; +class StoreManager; + +class StoreRef { + Store store; + StoreManager &mgr; +public: + StoreRef(Store, StoreManager &); + StoreRef(const StoreRef &); + StoreRef &operator=(StoreRef const &); + + bool operator==(const StoreRef &x) const { + assert(&mgr == &x.mgr); + return x.store == store; + } + bool operator!=(const StoreRef &x) const { return !operator==(x); } + ~StoreRef(); + + Store getStore() const { return store; } +}; + class StoreManager { protected: SValBuilder &svalBuilder; @@ -68,25 +88,22 @@ public: /// \return A pointer to a GRState object that contains the same bindings as /// \c state with the addition of having the value specified by \c val bound /// to the location given for \c loc. - virtual Store Bind(Store store, Loc loc, SVal val) = 0; - - virtual Store BindDefault(Store store, const MemRegion *R, SVal V) { - return store; - } + virtual StoreRef Bind(Store store, Loc loc, SVal val) = 0; - virtual Store Remove(Store St, Loc L) = 0; + virtual StoreRef BindDefault(Store store, const MemRegion *R, SVal V); + virtual StoreRef Remove(Store St, Loc L) = 0; /// BindCompoundLiteral - Return the store that has the bindings currently /// in 'store' plus the bindings for the CompoundLiteral. 'R' is the region /// for the compound literal and 'BegInit' and 'EndInit' represent an /// array of initializer values. - virtual Store BindCompoundLiteral(Store store, - const CompoundLiteralExpr* cl, - const LocationContext *LC, SVal v) = 0; + virtual StoreRef BindCompoundLiteral(Store store, + const CompoundLiteralExpr* cl, + const LocationContext *LC, SVal v) = 0; /// getInitialStore - Returns the initial "empty" store representing the /// value bindings upon entry to an analyzed function. - virtual Store getInitialStore(const LocationContext *InitLoc) = 0; + virtual StoreRef getInitialStore(const LocationContext *InitLoc) = 0; /// getRegionManager - Returns the internal RegionManager object that is /// used to query and manipulate MemRegion objects. @@ -153,13 +170,22 @@ public: /// casted and 'CastToTy' the result type of the cast. const MemRegion *castRegion(const MemRegion *region, QualType CastToTy); - virtual Store removeDeadBindings(Store store, const StackFrameContext *LCtx, - SymbolReaper& SymReaper, + virtual StoreRef removeDeadBindings(Store store, const StackFrameContext *LCtx, + SymbolReaper& SymReaper, llvm::SmallVectorImpl& RegionRoots) = 0; - virtual Store BindDecl(Store store, const VarRegion *VR, SVal initVal) = 0; + virtual StoreRef BindDecl(Store store, const VarRegion *VR, SVal initVal) = 0; - virtual Store BindDeclWithNoInit(Store store, const VarRegion *VR) = 0; + virtual StoreRef BindDeclWithNoInit(Store store, const VarRegion *VR) = 0; + + /// If the StoreManager supports it, increment the reference count of + /// the specified Store object. + virtual void incrementReferenceCount(Store store) {} + + /// If the StoreManager supports it, decrement the reference count of + /// the specified Store object. If the reference count hits 0, the memory + /// associated with the object is recycled. + virtual void decrementReferenceCount(Store store) {} typedef llvm::DenseSet InvalidatedSymbols; typedef llvm::SmallVector InvalidatedRegions; @@ -183,18 +209,18 @@ public: /// invalidated. This should include any regions explicitly invalidated /// even if they do not currently have bindings. Pass \c NULL if this /// information will not be used. - virtual Store invalidateRegions(Store store, - const MemRegion * const *Begin, - const MemRegion * const *End, - const Expr *E, unsigned Count, - InvalidatedSymbols *IS, - bool invalidateGlobals, - InvalidatedRegions *Regions) = 0; + virtual StoreRef invalidateRegions(Store store, + const MemRegion * const *Begin, + const MemRegion * const *End, + const Expr *E, unsigned Count, + InvalidatedSymbols *IS, + bool invalidateGlobals, + InvalidatedRegions *Regions) = 0; /// enterStackFrame - Let the StoreManager to do something when execution /// engine is about to execute into a callee. - virtual Store enterStackFrame(const GRState *state, - const StackFrameContext *frame); + virtual StoreRef enterStackFrame(const GRState *state, + const StackFrameContext *frame); virtual void print(Store store, llvm::raw_ostream& Out, const char* nl, const char *sep) = 0; @@ -223,6 +249,35 @@ private: SVal getLValueFieldOrIvar(const Decl* decl, SVal base); }; + +inline StoreRef::StoreRef(Store store, StoreManager & smgr) + : store(store), mgr(smgr) { + if (store) + mgr.incrementReferenceCount(store); +} + +inline StoreRef::StoreRef(const StoreRef &sr) + : store(sr.store), mgr(sr.mgr) +{ + if (store) + mgr.incrementReferenceCount(store); +} + +inline StoreRef::~StoreRef() { + if (store) + mgr.decrementReferenceCount(store); +} + +inline StoreRef &StoreRef::operator=(StoreRef const &newStore) { + assert(&newStore.mgr == &mgr); + if (store != newStore.store) { + mgr.incrementReferenceCount(newStore.store); + mgr.decrementReferenceCount(store); + store = newStore.getStore(); + } + return *this; +} + // FIXME: Do we still need this? /// SubRegionMap - An abstract interface that represents a queryable map /// between MemRegion objects and their subregions. diff --git a/lib/StaticAnalyzer/Core/BasicStore.cpp b/lib/StaticAnalyzer/Core/BasicStore.cpp index 987e790585..98365e7f4e 100644 --- a/lib/StaticAnalyzer/Core/BasicStore.cpp +++ b/lib/StaticAnalyzer/Core/BasicStore.cpp @@ -48,24 +48,25 @@ public: SVal Retrieve(Store store, Loc loc, QualType T = QualType()); - Store invalidateRegion(Store store, const MemRegion *R, const Expr *E, - unsigned Count, InvalidatedSymbols *IS); + StoreRef invalidateRegion(Store store, const MemRegion *R, const Expr *E, + unsigned Count, InvalidatedSymbols *IS); - Store invalidateRegions(Store store, const MemRegion * const *Begin, - const MemRegion * const *End, const Expr *E, - unsigned Count, InvalidatedSymbols *IS, - bool invalidateGlobals, InvalidatedRegions *Regions); + StoreRef invalidateRegions(Store store, const MemRegion * const *Begin, + const MemRegion * const *End, const Expr *E, + unsigned Count, InvalidatedSymbols *IS, + bool invalidateGlobals, + InvalidatedRegions *Regions); - Store scanForIvars(Stmt *B, const Decl* SelfDecl, - const MemRegion *SelfRegion, Store St); + StoreRef scanForIvars(Stmt *B, const Decl* SelfDecl, + const MemRegion *SelfRegion, Store St); - Store Bind(Store St, Loc loc, SVal V); - Store Remove(Store St, Loc loc); - Store getInitialStore(const LocationContext *InitLoc); + StoreRef Bind(Store St, Loc loc, SVal V); + StoreRef Remove(Store St, Loc loc); + StoreRef getInitialStore(const LocationContext *InitLoc); - Store BindCompoundLiteral(Store store, const CompoundLiteralExpr*, + StoreRef BindCompoundLiteral(Store store, const CompoundLiteralExpr*, const LocationContext*, SVal val) { - return store; + return StoreRef(store, *this); } /// ArrayToPointer - Used by ExprEngine::VistCast to handle implicit @@ -74,21 +75,21 @@ public: /// removeDeadBindings - Scans a BasicStore of 'state' for dead values. /// It updatees the GRState object in place with the values removed. - Store removeDeadBindings(Store store, const StackFrameContext *LCtx, - SymbolReaper& SymReaper, + StoreRef removeDeadBindings(Store store, const StackFrameContext *LCtx, + SymbolReaper& SymReaper, llvm::SmallVectorImpl& RegionRoots); void iterBindings(Store store, BindingsHandler& f); - Store BindDecl(Store store, const VarRegion *VR, SVal InitVal) { + StoreRef BindDecl(Store store, const VarRegion *VR, SVal InitVal) { return BindDeclInternal(store, VR, &InitVal); } - Store BindDeclWithNoInit(Store store, const VarRegion *VR) { + StoreRef BindDeclWithNoInit(Store store, const VarRegion *VR) { return BindDeclInternal(store, VR, 0); } - Store BindDeclInternal(Store store, const VarRegion *VR, SVal *InitVal); + StoreRef BindDeclInternal(Store store, const VarRegion *VR, SVal *InitVal); static inline BindingsTy GetBindings(Store store) { return BindingsTy(static_cast(store)); @@ -210,9 +211,9 @@ SVal BasicStoreManager::Retrieve(Store store, Loc loc, QualType T) { return UnknownVal(); } -Store BasicStoreManager::Bind(Store store, Loc loc, SVal V) { +StoreRef BasicStoreManager::Bind(Store store, Loc loc, SVal V) { if (isa(loc)) - return store; + return StoreRef(store, *this); const MemRegion* R = cast(loc).getRegion(); @@ -220,7 +221,7 @@ Store BasicStoreManager::Bind(Store store, Loc loc, SVal V) { // that is used to derive other symbols. if (isa(R)) { BindingsTy B = GetBindings(store); - return VBFactory.add(B, R, V).getRoot(); + return StoreRef(VBFactory.add(B, R, V).getRoot(), *this); } // Special case: handle store of pointer values (Loc) to pointers via @@ -236,14 +237,14 @@ Store BasicStoreManager::Bind(Store store, Loc loc, SVal V) { } if (!(isa(R) || isa(R) || isa(R))) - return store; + return StoreRef(store, *this); const TypedRegion *TyR = cast(R); // Do not bind to arrays. We need to explicitly check for this so that // we do not encounter any weirdness of trying to load/store from arrays. if (TyR->isBoundable() && TyR->getValueType()->isArrayType()) - return store; + return StoreRef(store, *this); if (nonloc::LocAsInteger *X = dyn_cast(&V)) { // Only convert 'V' to a location iff the underlying region type @@ -257,31 +258,31 @@ Store BasicStoreManager::Bind(Store store, Loc loc, SVal V) { } BindingsTy B = GetBindings(store); - return V.isUnknown() - ? VBFactory.remove(B, R).getRoot() - : VBFactory.add(B, R, V).getRoot(); + return StoreRef(V.isUnknown() + ? VBFactory.remove(B, R).getRoot() + : VBFactory.add(B, R, V).getRoot(), *this); } -Store BasicStoreManager::Remove(Store store, Loc loc) { +StoreRef BasicStoreManager::Remove(Store store, Loc loc) { switch (loc.getSubKind()) { case loc::MemRegionKind: { const MemRegion* R = cast(loc).getRegion(); if (!(isa(R) || isa(R) || isa(R))) - return store; + return StoreRef(store, *this); - return VBFactory.remove(GetBindings(store), R).getRoot(); + return StoreRef(VBFactory.remove(GetBindings(store), R).getRoot(), *this); } default: assert ("Remove for given Loc type not yet implemented."); - return store; + return StoreRef(store, *this); } } -Store BasicStoreManager::removeDeadBindings(Store store, - const StackFrameContext *LCtx, - SymbolReaper& SymReaper, +StoreRef BasicStoreManager::removeDeadBindings(Store store, + const StackFrameContext *LCtx, + SymbolReaper& SymReaper, llvm::SmallVectorImpl& RegionRoots) { BindingsTy B = GetBindings(store); @@ -347,11 +348,12 @@ Store BasicStoreManager::removeDeadBindings(Store store, } // Remove dead variable bindings. + StoreRef newStore(store, *this); for (BindingsTy::iterator I=B.begin(), E=B.end(); I!=E ; ++I) { const MemRegion* R = I.getKey(); if (!Marked.count(R)) { - store = Remove(store, svalBuilder.makeLoc(R)); + newStore = Remove(newStore.getStore(), svalBuilder.makeLoc(R)); SVal X = I.getData(); for (symbol_iterator SI=X.symbol_begin(), SE=X.symbol_end(); SI!=SE; ++SI) @@ -359,11 +361,15 @@ Store BasicStoreManager::removeDeadBindings(Store store, } } - return store; + return newStore; } -Store BasicStoreManager::scanForIvars(Stmt *B, const Decl* SelfDecl, - const MemRegion *SelfRegion, Store St) { +StoreRef BasicStoreManager::scanForIvars(Stmt *B, const Decl* SelfDecl, + const MemRegion *SelfRegion, + Store St) { + + StoreRef newStore(St, *this); + for (Stmt::child_iterator CI=B->child_begin(), CE=B->child_end(); CI != CE; ++CI) { @@ -379,24 +385,24 @@ Store BasicStoreManager::scanForIvars(Stmt *B, const Decl* SelfDecl, const ObjCIvarRegion *IVR = MRMgr.getObjCIvarRegion(IV->getDecl(), SelfRegion); SVal X = svalBuilder.getRegionValueSymbolVal(IVR); - St = Bind(St, svalBuilder.makeLoc(IVR), X); + newStore = Bind(newStore.getStore(), svalBuilder.makeLoc(IVR), X); } } } else - St = scanForIvars(*CI, SelfDecl, SelfRegion, St); + newStore = scanForIvars(*CI, SelfDecl, SelfRegion, newStore.getStore()); } - return St; + return newStore; } -Store BasicStoreManager::getInitialStore(const LocationContext *InitLoc) { +StoreRef BasicStoreManager::getInitialStore(const LocationContext *InitLoc) { // The LiveVariables information already has a compilation of all VarDecls // used in the function. Iterate through this set, and "symbolicate" // any VarDecl whose value originally comes from outside the function. typedef LiveVariables::AnalysisDataTy LVDataTy; LVDataTy& D = InitLoc->getLiveVariables()->getAnalysisData(); - Store St = VBFactory.getEmptyMap().getRoot(); + StoreRef St(VBFactory.getEmptyMap().getRoot(), *this); for (LVDataTy::decl_iterator I=D.begin_decl(), E=D.end_decl(); I != E; ++I) { const NamedDecl* ND = I->first; @@ -412,10 +418,11 @@ Store BasicStoreManager::getInitialStore(const LocationContext *InitLoc) { const MemRegion *SelfRegion = svalBuilder.getRegionValueSymbolVal(VR).getAsRegion(); assert(SelfRegion); - St = Bind(St, svalBuilder.makeLoc(VR), loc::MemRegionVal(SelfRegion)); + St = Bind(St.getStore(), svalBuilder.makeLoc(VR), + loc::MemRegionVal(SelfRegion)); // Scan the method for ivar references. While this requires an // entire AST scan, the cost should not be high in practice. - St = scanForIvars(MD->getBody(), PD, SelfRegion, St); + St = scanForIvars(MD->getBody(), PD, SelfRegion, St.getStore()); } } } @@ -427,22 +434,23 @@ Store BasicStoreManager::getInitialStore(const LocationContext *InitLoc) { MemRegionManager &RegMgr = svalBuilder.getRegionManager(); const CXXThisRegion *ThisR = RegMgr.getCXXThisRegion(ThisT, InitLoc); SVal ThisV = svalBuilder.getRegionValueSymbolVal(ThisR); - St = Bind(St, svalBuilder.makeLoc(ThisR), ThisV); + St = Bind(St.getStore(), svalBuilder.makeLoc(ThisR), ThisV); } return St; } -Store BasicStoreManager::BindDeclInternal(Store store, const VarRegion* VR, - SVal* InitVal) { +StoreRef BasicStoreManager::BindDeclInternal(Store store, const VarRegion* VR, + SVal* InitVal) { BasicValueFactory& BasicVals = StateMgr.getBasicVals(); const VarDecl *VD = VR->getDecl(); + StoreRef newStore(store, *this); // BasicStore does not model arrays and structs. if (VD->getType()->isArrayType() || VD->getType()->isStructureOrClassType()) - return store; - + return newStore; + if (VD->hasGlobalStorage()) { // Handle variables with global storage: extern, static, PrivateExtern. @@ -465,13 +473,13 @@ Store BasicStoreManager::BindDeclInternal(Store store, const VarRegion* VR, if (!InitVal) { QualType T = VD->getType(); if (Loc::isLocType(T)) - store = Bind(store, loc::MemRegionVal(VR), - loc::ConcreteInt(BasicVals.getValue(0, T))); + newStore = Bind(store, loc::MemRegionVal(VR), + loc::ConcreteInt(BasicVals.getValue(0, T))); else if (T->isIntegerType() && T->isScalarType()) - store = Bind(store, loc::MemRegionVal(VR), - nonloc::ConcreteInt(BasicVals.getValue(0, T))); + newStore = Bind(store, loc::MemRegionVal(VR), + nonloc::ConcreteInt(BasicVals.getValue(0, T))); } else { - store = Bind(store, loc::MemRegionVal(VR), *InitVal); + newStore = Bind(store, loc::MemRegionVal(VR), *InitVal); } } } else { @@ -481,11 +489,11 @@ Store BasicStoreManager::BindDeclInternal(Store store, const VarRegion* VR, if ((T->isScalarType() || T->isReferenceType()) && svalBuilder.getSymbolManager().canSymbolicate(T)) { SVal V = InitVal ? *InitVal : UndefinedVal(); - store = Bind(store, loc::MemRegionVal(VR), V); + newStore = Bind(store, loc::MemRegionVal(VR), V); } } - return store; + return newStore; } void BasicStoreManager::print(Store store, llvm::raw_ostream& Out, @@ -523,19 +531,21 @@ StoreManager::BindingsHandler::~BindingsHandler() {} //===----------------------------------------------------------------------===// -Store BasicStoreManager::invalidateRegions(Store store, - const MemRegion * const *I, - const MemRegion * const *End, - const Expr *E, unsigned Count, - InvalidatedSymbols *IS, - bool invalidateGlobals, - InvalidatedRegions *Regions) { +StoreRef BasicStoreManager::invalidateRegions(Store store, + const MemRegion * const *I, + const MemRegion * const *End, + const Expr *E, unsigned Count, + InvalidatedSymbols *IS, + bool invalidateGlobals, + InvalidatedRegions *Regions) { + StoreRef newStore(store, *this); + if (invalidateGlobals) { BindingsTy B = GetBindings(store); for (BindingsTy::iterator I=B.begin(), End=B.end(); I != End; ++I) { const MemRegion *R = I.getKey(); if (isa(R->getMemorySpace())) - store = invalidateRegion(store, R, E, Count, IS); + newStore = invalidateRegion(newStore.getStore(), R, E, Count, IS); } } @@ -546,7 +556,7 @@ Store BasicStoreManager::invalidateRegions(Store store, if (isa(R->getMemorySpace())) continue; } - store = invalidateRegion(store, *I, E, Count, IS); + newStore = invalidateRegion(newStore.getStore(), *I, E, Count, IS); if (Regions) Regions->push_back(R); } @@ -561,24 +571,24 @@ Store BasicStoreManager::invalidateRegions(Store store, /* symbol type, doesn't matter */ Ctx.IntTy, Count); - store = Bind(store, loc::MemRegionVal(GS), V); + newStore = Bind(newStore.getStore(), loc::MemRegionVal(GS), V); if (Regions) Regions->push_back(GS); } - return store; + return newStore; } -Store BasicStoreManager::invalidateRegion(Store store, - const MemRegion *R, - const Expr *E, - unsigned Count, - InvalidatedSymbols *IS) { +StoreRef BasicStoreManager::invalidateRegion(Store store, + const MemRegion *R, + const Expr *E, + unsigned Count, + InvalidatedSymbols *IS) { R = R->StripCasts(); if (!(isa(R) || isa(R))) - return store; + return StoreRef(store, *this); if (IS) { BindingsTy B = GetBindings(store); diff --git a/lib/StaticAnalyzer/Core/FlatStore.cpp b/lib/StaticAnalyzer/Core/FlatStore.cpp index c3da72af5a..99a5eadaca 100644 --- a/lib/StaticAnalyzer/Core/FlatStore.cpp +++ b/lib/StaticAnalyzer/Core/FlatStore.cpp @@ -31,13 +31,13 @@ public: BVFactory(mgr.getAllocator()) {} SVal Retrieve(Store store, Loc L, QualType T); - Store Bind(Store store, Loc L, SVal val); - Store Remove(Store St, Loc L); - Store BindCompoundLiteral(Store store, const CompoundLiteralExpr* cl, + StoreRef Bind(Store store, Loc L, SVal val); + StoreRef Remove(Store St, Loc L); + StoreRef BindCompoundLiteral(Store store, const CompoundLiteralExpr* cl, const LocationContext *LC, SVal v); - Store getInitialStore(const LocationContext *InitLoc) { - return RBFactory.getEmptyMap().getRoot(); + StoreRef getInitialStore(const LocationContext *InitLoc) { + return StoreRef(RBFactory.getEmptyMap().getRoot(), *this); } SubRegionMap *getSubRegionMap(Store store) { @@ -45,22 +45,23 @@ public: } SVal ArrayToPointer(Loc Array); - Store removeDeadBindings(Store store, const StackFrameContext *LCtx, - SymbolReaper& SymReaper, - llvm::SmallVectorImpl& RegionRoots){ - return store; + StoreRef removeDeadBindings(Store store, const StackFrameContext *LCtx, + SymbolReaper& SymReaper, + llvm::SmallVectorImpl& RegionRoots){ + return StoreRef(store, *this); } - Store BindDecl(Store store, const VarRegion *VR, SVal initVal); + StoreRef BindDecl(Store store, const VarRegion *VR, SVal initVal); - Store BindDeclWithNoInit(Store store, const VarRegion *VR); + StoreRef BindDeclWithNoInit(Store store, const VarRegion *VR); typedef llvm::DenseSet InvalidatedSymbols; - Store invalidateRegions(Store store, const MemRegion * const *I, - const MemRegion * const *E, const Expr *Ex, - unsigned Count, InvalidatedSymbols *IS, - bool invalidateGlobals, InvalidatedRegions *Regions); + StoreRef invalidateRegions(Store store, const MemRegion * const *I, + const MemRegion * const *E, const Expr *Ex, + unsigned Count, InvalidatedSymbols *IS, + bool invalidateGlobals, + InvalidatedRegions *Regions); void print(Store store, llvm::raw_ostream& Out, const char* nl, const char *sep); @@ -115,7 +116,7 @@ SVal FlatStoreManager::RetrieveRegionWithNoBinding(const MemRegion *R, return svalBuilder.getRegionValueSymbolVal(cast(R)); } -Store FlatStoreManager::Bind(Store store, Loc L, SVal val) { +StoreRef FlatStoreManager::Bind(Store store, Loc L, SVal val) { const MemRegion *R = cast(L).getRegion(); RegionBindings B = getRegionBindings(store); const BindingVal *V = B.lookup(R); @@ -127,45 +128,45 @@ Store FlatStoreManager::Bind(Store store, Loc L, SVal val) { RegionInterval RI = RegionToInterval(R); // FIXME: FlatStore should handle regions with unknown intervals. if (!RI.R) - return B.getRoot(); + return StoreRef(B.getRoot(), *this); BV = BVFactory.add(BV, RI.I, val); B = RBFactory.add(B, RI.R, BV); - return B.getRoot(); + return StoreRef(B.getRoot(), *this); } -Store FlatStoreManager::Remove(Store store, Loc L) { - return store; +StoreRef FlatStoreManager::Remove(Store store, Loc L) { + return StoreRef(store, *this); } -Store FlatStoreManager::BindCompoundLiteral(Store store, +StoreRef FlatStoreManager::BindCompoundLiteral(Store store, const CompoundLiteralExpr* cl, const LocationContext *LC, SVal v) { - return store; + return StoreRef(store, *this); } SVal FlatStoreManager::ArrayToPointer(Loc Array) { return Array; } -Store FlatStoreManager::BindDecl(Store store, const VarRegion *VR, - SVal initVal) { +StoreRef FlatStoreManager::BindDecl(Store store, const VarRegion *VR, + SVal initVal) { return Bind(store, svalBuilder.makeLoc(VR), initVal); } -Store FlatStoreManager::BindDeclWithNoInit(Store store, const VarRegion *VR) { - return store; +StoreRef FlatStoreManager::BindDeclWithNoInit(Store store, const VarRegion *VR){ + return StoreRef(store, *this); } -Store FlatStoreManager::invalidateRegions(Store store, - const MemRegion * const *I, - const MemRegion * const *E, - const Expr *Ex, unsigned Count, - InvalidatedSymbols *IS, - bool invalidateGlobals, - InvalidatedRegions *Regions) { +StoreRef FlatStoreManager::invalidateRegions(Store store, + const MemRegion * const *I, + const MemRegion * const *E, + const Expr *Ex, unsigned Count, + InvalidatedSymbols *IS, + bool invalidateGlobals, + InvalidatedRegions *Regions) { assert(false && "Not implemented"); - return store; + return StoreRef(store, *this); } void FlatStoreManager::print(Store store, llvm::raw_ostream& Out, diff --git a/lib/StaticAnalyzer/Core/GRState.cpp b/lib/StaticAnalyzer/Core/GRState.cpp index 80c8bbf195..7defecb366 100644 --- a/lib/StaticAnalyzer/Core/GRState.cpp +++ b/lib/StaticAnalyzer/Core/GRState.cpp @@ -53,7 +53,7 @@ GRStateManager::removeDeadBindings(const GRState* state, state, RegionRoots); // Clean up the store. - NewState.St = StoreMgr->removeDeadBindings(NewState.St, LCtx, + NewState.St = StoreMgr->removeDeadBindings(NewState.getStore(), LCtx, SymReaper, RegionRoots); state = getPersistentState(NewState); return ConstraintMgr->removeDeadBindings(state, SymReaper); @@ -73,38 +73,39 @@ const GRState *GRStateManager::MarshalState(const GRState *state, const GRState *GRState::bindCompoundLiteral(const CompoundLiteralExpr* CL, const LocationContext *LC, SVal V) const { - Store new_store = - getStateManager().StoreMgr->BindCompoundLiteral(St, CL, LC, V); - return makeWithStore(new_store); + const StoreRef &newStore = + getStateManager().StoreMgr->BindCompoundLiteral(getStore(), CL, LC, V); + return makeWithStore(newStore); } const GRState *GRState::bindDecl(const VarRegion* VR, SVal IVal) const { - Store new_store = getStateManager().StoreMgr->BindDecl(St, VR, IVal); - return makeWithStore(new_store); + const StoreRef &newStore = + getStateManager().StoreMgr->BindDecl(getStore(), VR, IVal); + return makeWithStore(newStore); } const GRState *GRState::bindDeclWithNoInit(const VarRegion* VR) const { - Store new_store = getStateManager().StoreMgr->BindDeclWithNoInit(St, VR); - return makeWithStore(new_store); + const StoreRef &newStore = + getStateManager().StoreMgr->BindDeclWithNoInit(getStore(), VR); + return makeWithStore(newStore); } const GRState *GRState::bindLoc(Loc LV, SVal V) const { GRStateManager &Mgr = getStateManager(); - Store new_store = Mgr.StoreMgr->Bind(St, LV, V); - const GRState *new_state = makeWithStore(new_store); - + const GRState *newState = makeWithStore(Mgr.StoreMgr->Bind(getStore(), + LV, V)); const MemRegion *MR = LV.getAsRegion(); if (MR && Mgr.getOwningEngine()) - return Mgr.getOwningEngine()->processRegionChange(new_state, MR); + return Mgr.getOwningEngine()->processRegionChange(newState, MR); - return new_state; + return newState; } const GRState *GRState::bindDefault(SVal loc, SVal V) const { GRStateManager &Mgr = getStateManager(); const MemRegion *R = cast(loc).getRegion(); - Store new_store = Mgr.StoreMgr->BindDefault(St, R, V); - const GRState *new_state = makeWithStore(new_store); + const StoreRef &newStore = Mgr.StoreMgr->BindDefault(getStore(), R, V); + const GRState *new_state = makeWithStore(newStore); return Mgr.getOwningEngine() ? Mgr.getOwningEngine()->processRegionChange(new_state, R) : new_state; @@ -120,39 +121,36 @@ const GRState *GRState::invalidateRegions(const MemRegion * const *Begin, if (Eng && Eng->wantsRegionChangeUpdate(this)) { StoreManager::InvalidatedRegions Regions; - - Store new_store = Mgr.StoreMgr->invalidateRegions(St, Begin, End, - E, Count, IS, - invalidateGlobals, - &Regions); - const GRState *new_state = makeWithStore(new_store); - - return Eng->processRegionChanges(new_state, + const StoreRef &newStore + = Mgr.StoreMgr->invalidateRegions(getStore(), Begin, End, E, Count, IS, + invalidateGlobals, &Regions); + const GRState *newState = makeWithStore(newStore); + return Eng->processRegionChanges(newState, &Regions.front(), &Regions.back()+1); } - Store new_store = Mgr.StoreMgr->invalidateRegions(St, Begin, End, - E, Count, IS, - invalidateGlobals, - NULL); - return makeWithStore(new_store); + const StoreRef &newStore = + Mgr.StoreMgr->invalidateRegions(getStore(), Begin, End, E, Count, IS, + invalidateGlobals, NULL); + return makeWithStore(newStore); } const GRState *GRState::unbindLoc(Loc LV) const { assert(!isa(LV) && "Use invalidateRegion instead."); Store OldStore = getStore(); - Store NewStore = getStateManager().StoreMgr->Remove(OldStore, LV); + const StoreRef &newStore = getStateManager().StoreMgr->Remove(OldStore, LV); - if (NewStore == OldStore) + if (newStore.getStore() == OldStore) return this; - return makeWithStore(NewStore); + return makeWithStore(newStore); } const GRState *GRState::enterStackFrame(const StackFrameContext *frame) const { - Store new_store = getStateManager().StoreMgr->enterStackFrame(this, frame); + const StoreRef &new_store = + getStateManager().StoreMgr->enterStackFrame(this, frame); return makeWithStore(new_store); } @@ -323,7 +321,7 @@ const GRState* GRStateManager::getPersistentState(GRState& State) { return newState; } -const GRState* GRState::makeWithStore(Store store) const { +const GRState* GRState::makeWithStore(const StoreRef &store) const { GRState NewSt = *this; NewSt.St = store; return getStateManager().getPersistentState(NewSt); diff --git a/lib/StaticAnalyzer/Core/RegionStore.cpp b/lib/StaticAnalyzer/Core/RegionStore.cpp index dc31715ccb..19e0e12572 100644 --- a/lib/StaticAnalyzer/Core/RegionStore.cpp +++ b/lib/StaticAnalyzer/Core/RegionStore.cpp @@ -215,7 +215,7 @@ public: /// setImplicitDefaultValue - Set the default binding for the provided /// MemRegion to the value implicitly defined for compound literals when /// the value is not specified. - Store setImplicitDefaultValue(Store store, const MemRegion *R, QualType T); + StoreRef setImplicitDefaultValue(Store store, const MemRegion *R, QualType T); /// ArrayToPointer - Emulates the "decay" of an array to a pointer /// type. 'Array' represents the lvalue of the array being decayed @@ -228,21 +228,21 @@ public: /// For DerivedToBase casts, create a CXXBaseObjectRegion and return it. virtual SVal evalDerivedToBase(SVal derived, QualType basePtrType); - Store getInitialStore(const LocationContext *InitLoc) { - return RBFactory.getEmptyMap().getRoot(); + StoreRef getInitialStore(const LocationContext *InitLoc) { + return StoreRef(RBFactory.getEmptyMap().getRootWithoutRetain(), *this); } //===-------------------------------------------------------------------===// // Binding values to regions. //===-------------------------------------------------------------------===// - Store invalidateRegions(Store store, - const MemRegion * const *Begin, - const MemRegion * const *End, - const Expr *E, unsigned Count, - InvalidatedSymbols *IS, - bool invalidateGlobals, - InvalidatedRegions *Regions); + StoreRef invalidateRegions(Store store, + const MemRegion * const *Begin, + const MemRegion * const *End, + const Expr *E, unsigned Count, + InvalidatedSymbols *IS, + bool invalidateGlobals, + InvalidatedRegions *Regions); public: // Made public for helper classes. @@ -268,35 +268,45 @@ public: // Made public for helper classes. public: // Part of public interface to class. - Store Bind(Store store, Loc LV, SVal V); + StoreRef Bind(Store store, Loc LV, SVal V); // BindDefault is only used to initialize a region with a default value. - Store BindDefault(Store store, const MemRegion *R, SVal V) { + StoreRef BindDefault(Store store, const MemRegion *R, SVal V) { RegionBindings B = GetRegionBindings(store); assert(!lookup(B, R, BindingKey::Default)); assert(!lookup(B, R, BindingKey::Direct)); - return addBinding(B, R, BindingKey::Default, V).getRoot(); + return StoreRef(addBinding(B, R, BindingKey::Default, V).getRootWithoutRetain(), *this); } - Store BindCompoundLiteral(Store store, const CompoundLiteralExpr* CL, - const LocationContext *LC, SVal V); + StoreRef BindCompoundLiteral(Store store, const CompoundLiteralExpr* CL, + const LocationContext *LC, SVal V); - Store BindDecl(Store store, const VarRegion *VR, SVal InitVal); + StoreRef BindDecl(Store store, const VarRegion *VR, SVal InitVal); - Store BindDeclWithNoInit(Store store, const VarRegion *) { - return store; + StoreRef BindDeclWithNoInit(Store store, const VarRegion *) { + return StoreRef(store, *this); } /// BindStruct - Bind a compound value to a structure. - Store BindStruct(Store store, const TypedRegion* R, SVal V); + StoreRef BindStruct(Store store, const TypedRegion* R, SVal V); - Store BindArray(Store store, const TypedRegion* R, SVal V); + StoreRef BindArray(Store store, const TypedRegion* R, SVal V); /// KillStruct - Set the entire struct to unknown. - Store KillStruct(Store store, const TypedRegion* R, SVal DefaultVal); + StoreRef KillStruct(Store store, const TypedRegion* R, SVal DefaultVal); - Store Remove(Store store, Loc LV); + StoreRef Remove(Store store, Loc LV); + void incrementReferenceCount(Store store) { + GetRegionBindings(store).manualRetain(); + } + + /// If the StoreManager supports it, decrement the reference count of + /// the specified Store object. If the reference count hits 0, the memory + /// associated with the object is recycled. + void decrementReferenceCount(Store store) { + GetRegionBindings(store).manualRelease(); + } //===------------------------------------------------------------------===// // Loading values from regions. @@ -347,8 +357,8 @@ public: // Part of public interface to class. std::pair GetLazyBinding(RegionBindings B, const MemRegion *R); - Store CopyLazyBindings(nonloc::LazyCompoundVal V, Store store, - const TypedRegion *R); + StoreRef CopyLazyBindings(nonloc::LazyCompoundVal V, Store store, + const TypedRegion *R); //===------------------------------------------------------------------===// // State pruning. @@ -356,11 +366,11 @@ public: // Part of public interface to class. /// removeDeadBindings - Scans the RegionStore of 'state' for dead values. /// It returns a new Store with these values removed. - Store removeDeadBindings(Store store, const StackFrameContext *LCtx, + StoreRef removeDeadBindings(Store store, const StackFrameContext *LCtx, SymbolReaper& SymReaper, llvm::SmallVectorImpl& RegionRoots); - Store enterStackFrame(const GRState *state, const StackFrameContext *frame); + StoreRef enterStackFrame(const GRState *state, const StackFrameContext *frame); //===------------------------------------------------------------------===// // Region "extents". @@ -706,13 +716,13 @@ void invalidateRegionsWorker::VisitBaseRegion(const MemRegion *baseR) { B = RM.addBinding(B, baseR, BindingKey::Direct, V); } -Store RegionStoreManager::invalidateRegions(Store store, - const MemRegion * const *I, - const MemRegion * const *E, - const Expr *Ex, unsigned Count, - InvalidatedSymbols *IS, - bool invalidateGlobals, - InvalidatedRegions *Regions) { +StoreRef RegionStoreManager::invalidateRegions(Store store, + const MemRegion * const *I, + const MemRegion * const *E, + const Expr *Ex, unsigned Count, + InvalidatedSymbols *IS, + bool invalidateGlobals, + InvalidatedRegions *Regions) { invalidateRegionsWorker W(*this, StateMgr, RegionStoreManager::GetRegionBindings(store), Ex, Count, IS, Regions, invalidateGlobals); @@ -745,7 +755,7 @@ Store RegionStoreManager::invalidateRegions(Store store, Regions->push_back(GS); } - return B.getRoot(); + return StoreRef(B.getRootWithoutRetain(), *this); } //===----------------------------------------------------------------------===// @@ -1252,17 +1262,19 @@ SVal RegionStoreManager::RetrieveArray(Store store, const TypedRegion * R) { // Binding values to regions. //===----------------------------------------------------------------------===// -Store RegionStoreManager::Remove(Store store, Loc L) { +StoreRef RegionStoreManager::Remove(Store store, Loc L) { if (isa(L)) if (const MemRegion* R = cast(L).getRegion()) - return removeBinding(GetRegionBindings(store), R).getRoot(); + return StoreRef(removeBinding(GetRegionBindings(store), + R).getRootWithoutRetain(), + *this); - return store; + return StoreRef(store, *this); } -Store RegionStoreManager::Bind(Store store, Loc L, SVal V) { +StoreRef RegionStoreManager::Bind(Store store, Loc L, SVal V) { if (isa(L)) - return store; + return StoreRef(store, *this); // If we get here, the location should be a region. const MemRegion *R = cast(L).getRegion(); @@ -1301,11 +1313,12 @@ Store RegionStoreManager::Bind(Store store, Loc L, SVal V) { // Perform the binding. RegionBindings B = GetRegionBindings(store); - return addBinding(B, R, BindingKey::Direct, V).getRoot(); + return StoreRef(addBinding(B, R, BindingKey::Direct, + V).getRootWithoutRetain(), *this); } -Store RegionStoreManager::BindDecl(Store store, const VarRegion *VR, - SVal InitVal) { +StoreRef RegionStoreManager::BindDecl(Store store, const VarRegion *VR, + SVal InitVal) { QualType T = VR->getDecl()->getType(); @@ -1318,18 +1331,17 @@ Store RegionStoreManager::BindDecl(Store store, const VarRegion *VR, } // FIXME: this method should be merged into Bind(). -Store RegionStoreManager::BindCompoundLiteral(Store store, - const CompoundLiteralExpr *CL, - const LocationContext *LC, - SVal V) { +StoreRef RegionStoreManager::BindCompoundLiteral(Store store, + const CompoundLiteralExpr *CL, + const LocationContext *LC, + SVal V) { return Bind(store, loc::MemRegionVal(MRMgr.getCompoundLiteralRegion(CL, LC)), V); } - -Store RegionStoreManager::setImplicitDefaultValue(Store store, - const MemRegion *R, - QualType T) { +StoreRef RegionStoreManager::setImplicitDefaultValue(Store store, + const MemRegion *R, + QualType T) { RegionBindings B = GetRegionBindings(store); SVal V; @@ -1343,14 +1355,15 @@ Store RegionStoreManager::setImplicitDefaultValue(Store store, V = svalBuilder.makeZeroVal(Ctx.IntTy); } else { - return store; + return StoreRef(store, *this); } - return addBinding(B, R, BindingKey::Default, V).getRoot(); + return StoreRef(addBinding(B, R, BindingKey::Default, + V).getRootWithoutRetain(), *this); } -Store RegionStoreManager::BindArray(Store store, const TypedRegion* R, - SVal Init) { +StoreRef RegionStoreManager::BindArray(Store store, const TypedRegion* R, + SVal Init) { const ArrayType *AT =cast(Ctx.getCanonicalType(R->getValueType())); QualType ElementTy = AT->getElementType(); @@ -1382,6 +1395,7 @@ Store RegionStoreManager::BindArray(Store store, const TypedRegion* R, nonloc::CompoundVal::iterator VI = CV.begin(), VE = CV.end(); uint64_t i = 0; + StoreRef newStore(store, *this); for (; Size.hasValue() ? i < Size.getValue() : true ; ++i, ++VI) { // The init list might be shorter than the array length. if (VI == VE) @@ -1391,26 +1405,26 @@ Store RegionStoreManager::BindArray(Store store, const TypedRegion* R, const ElementRegion *ER = MRMgr.getElementRegion(ElementTy, Idx, R, Ctx); if (ElementTy->isStructureOrClassType()) - store = BindStruct(store, ER, *VI); + newStore = BindStruct(newStore.getStore(), ER, *VI); else if (ElementTy->isArrayType()) - store = BindArray(store, ER, *VI); + newStore = BindArray(newStore.getStore(), ER, *VI); else - store = Bind(store, svalBuilder.makeLoc(ER), *VI); + newStore = Bind(newStore.getStore(), svalBuilder.makeLoc(ER), *VI); } // If the init list is shorter than the array length, set the // array default value. if (Size.hasValue() && i < Size.getValue()) - store = setImplicitDefaultValue(store, R, ElementTy); + newStore = setImplicitDefaultValue(newStore.getStore(), R, ElementTy); - return store; + return newStore; } -Store RegionStoreManager::BindStruct(Store store, const TypedRegion* R, - SVal V) { +StoreRef RegionStoreManager::BindStruct(Store store, const TypedRegion* R, + SVal V) { if (!Features.supportsFields()) - return store; + return StoreRef(store, *this); QualType T = R->getValueType(); assert(T->isStructureOrClassType()); @@ -1419,7 +1433,7 @@ Store RegionStoreManager::BindStruct(Store store, const TypedRegion* R, RecordDecl* RD = RT->getDecl(); if (!RD->isDefinition()) - return store; + return StoreRef(store, *this); // Handle lazy compound values. if (const nonloc::LazyCompoundVal *LCV=dyn_cast(&V)) @@ -1437,7 +1451,8 @@ Store RegionStoreManager::BindStruct(Store store, const TypedRegion* R, nonloc::CompoundVal::iterator VI = CV.begin(), VE = CV.end(); RecordDecl::field_iterator FI, FE; - + StoreRef newStore(store, *this); + for (FI = RD->field_begin(), FE = RD->field_end(); FI != FE; ++FI, ++VI) { if (VI == VE) @@ -1447,24 +1462,24 @@ Store RegionStoreManager::BindStruct(Store store, const TypedRegion* R, const FieldRegion* FR = MRMgr.getFieldRegion(*FI, R); if (FTy->isArrayType()) - store = BindArray(store, FR, *VI); + newStore = BindArray(newStore.getStore(), FR, *VI); else if (FTy->isStructureOrClassType()) - store = BindStruct(store, FR, *VI); + newStore = BindStruct(newStore.getStore(), FR, *VI); else - store = Bind(store, svalBuilder.makeLoc(FR), *VI); + newStore = Bind(newStore.getStore(), svalBuilder.makeLoc(FR), *VI); } // There may be fewer values in the initialize list than the fields of struct. if (FI != FE) { - RegionBindings B = GetRegionBindings(store); + RegionBindings B = GetRegionBindings(newStore.getStore()); B = addBinding(B, R, BindingKey::Default, svalBuilder.makeIntVal(0, false)); - store = B.getRoot(); + newStore = StoreRef(B.getRootWithoutRetain(), *this); } - return store; + return newStore; } -Store RegionStoreManager::KillStruct(Store store, const TypedRegion* R, +StoreRef RegionStoreManager::KillStruct(Store store, const TypedRegion* R, SVal DefaultVal) { BindingKey key = BindingKey::Make(R, BindingKey::Default); @@ -1494,13 +1509,14 @@ Store RegionStoreManager::KillStruct(Store store, const TypedRegion* R, // Set the default value of the struct region to "unknown". if (!key.isValid()) - return B.getRoot(); + return StoreRef(B.getRootWithoutRetain(), *this); - return addBinding(B, key, DefaultVal).getRoot(); + return StoreRef(addBinding(B, key, DefaultVal).getRootWithoutRetain(), *this); } -Store RegionStoreManager::CopyLazyBindings(nonloc::LazyCompoundVal V, - Store store, const TypedRegion *R) { +StoreRef RegionStoreManager::CopyLazyBindings(nonloc::LazyCompoundVal V, + Store store, + const TypedRegion *R) { // Nuke the old bindings stemming from R. RegionBindings B = GetRegionBindings(store); @@ -1513,7 +1529,8 @@ Store RegionStoreManager::CopyLazyBindings(nonloc::LazyCompoundVal V, // Now copy the bindings. This amounts to just binding 'V' to 'R'. This // results in a zero-copy algorithm. - return addBinding(B, R, BindingKey::Direct, V).getRoot(); + return StoreRef(addBinding(B, R, BindingKey::Direct, + V).getRootWithoutRetain(), *this); } //===----------------------------------------------------------------------===// @@ -1704,9 +1721,9 @@ bool removeDeadBindingsWorker::UpdatePostponed() { return changed; } -Store RegionStoreManager::removeDeadBindings(Store store, - const StackFrameContext *LCtx, - SymbolReaper& SymReaper, +StoreRef RegionStoreManager::removeDeadBindings(Store store, + const StackFrameContext *LCtx, + SymbolReaper& SymReaper, llvm::SmallVectorImpl& RegionRoots) { RegionBindings B = GetRegionBindings(store); @@ -1743,16 +1760,16 @@ Store RegionStoreManager::removeDeadBindings(Store store, SymReaper.maybeDead(*SI); } - return B.getRoot(); + return StoreRef(B.getRootWithoutRetain(), *this); } -Store RegionStoreManager::enterStackFrame(const GRState *state, - const StackFrameContext *frame) { +StoreRef RegionStoreManager::enterStackFrame(const GRState *state, + const StackFrameContext *frame) { FunctionDecl const *FD = cast(frame->getDecl()); FunctionDecl::param_const_iterator PI = FD->param_begin(), PE = FD->param_end(); - Store store = state->getStore(); + StoreRef store = StoreRef(state->getStore(), *this); if (CallExpr const *CE = dyn_cast(frame->getCallSite())) { CallExpr::const_arg_iterator AI = CE->arg_begin(), AE = CE->arg_end(); @@ -1762,7 +1779,7 @@ Store RegionStoreManager::enterStackFrame(const GRState *state, // the function declaration. for (; AI != AE && PI != PE; ++AI, ++PI) { SVal ArgVal = state->getSVal(*AI); - store = Bind(store, + store = Bind(store.getStore(), svalBuilder.makeLoc(MRMgr.getVarRegion(*PI, frame)), ArgVal); } } else if (const CXXConstructExpr *CE = @@ -1773,7 +1790,7 @@ Store RegionStoreManager::enterStackFrame(const GRState *state, // Copy the arg expression value to the arg variables. for (; AI != AE; ++AI, ++PI) { SVal ArgVal = state->getSVal(*AI); - store = Bind(store, + store = Bind(store.getStore(), svalBuilder.makeLoc(MRMgr.getVarRegion(*PI,frame)), ArgVal); } } else diff --git a/lib/StaticAnalyzer/Core/Store.cpp b/lib/StaticAnalyzer/Core/Store.cpp index 28f890b39c..379327fbb5 100644 --- a/lib/StaticAnalyzer/Core/Store.cpp +++ b/lib/StaticAnalyzer/Core/Store.cpp @@ -22,9 +22,9 @@ StoreManager::StoreManager(GRStateManager &stateMgr) : svalBuilder(stateMgr.getSValBuilder()), StateMgr(stateMgr), MRMgr(svalBuilder.getRegionManager()), Ctx(stateMgr.getContext()) {} -Store StoreManager::enterStackFrame(const GRState *state, - const StackFrameContext *frame) { - return state->getStore(); +StoreRef StoreManager::enterStackFrame(const GRState *state, + const StackFrameContext *frame) { + return StoreRef(state->getStore(), *this); } const MemRegion *StoreManager::MakeElementRegion(const MemRegion *Base, @@ -44,6 +44,10 @@ static bool IsCompleteType(ASTContext &Ctx, QualType Ty) { return true; } +StoreRef StoreManager::BindDefault(Store store, const MemRegion *R, SVal V) { + return StoreRef(store, *this); +} + const ElementRegion *StoreManager::GetElementZeroRegion(const MemRegion *R, QualType T) { NonLoc idx = svalBuilder.makeZeroArrayIndex();