aboutsummaryrefslogtreecommitdiff
path: root/lib/StaticAnalyzer/Core/BasicStore.cpp
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2011-02-19 01:59:33 +0000
committerTed Kremenek <kremenek@apple.com>2011-02-19 01:59:33 +0000
commit77a4d5687c2cb3199c689892c9d040a94ff270af (patch)
tree2de2bb3aebfd7f4c982d64744324c6a486ccd830 /lib/StaticAnalyzer/Core/BasicStore.cpp
parent7ff07dce18a7c693fe1a15bd7b790d8de9d21e92 (diff)
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
Diffstat (limited to 'lib/StaticAnalyzer/Core/BasicStore.cpp')
-rw-r--r--lib/StaticAnalyzer/Core/BasicStore.cpp156
1 files changed, 83 insertions, 73 deletions
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<const MemRegion*>& 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<const BindingsTy::TreeTy*>(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::ConcreteInt>(loc))
- return store;
+ return StoreRef(store, *this);
const MemRegion* R = cast<loc::MemRegionVal>(loc).getRegion();
@@ -220,7 +221,7 @@ Store BasicStoreManager::Bind(Store store, Loc loc, SVal V) {
// that is used to derive other symbols.
if (isa<NonStaticGlobalSpaceRegion>(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<VarRegion>(R) || isa<ObjCIvarRegion>(R) || isa<CXXThisRegion>(R)))
- return store;
+ return StoreRef(store, *this);
const TypedRegion *TyR = cast<TypedRegion>(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<nonloc::LocAsInteger>(&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::MemRegionVal>(loc).getRegion();
if (!(isa<VarRegion>(R) || isa<ObjCIvarRegion>(R) ||
isa<CXXThisRegion>(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<const MemRegion*>& 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<NonStaticGlobalSpaceRegion>(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<NonStaticGlobalSpaceRegion>(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<VarRegion>(R) || isa<ObjCIvarRegion>(R)))
- return store;
+ return StoreRef(store, *this);
if (IS) {
BindingsTy B = GetBindings(store);