aboutsummaryrefslogtreecommitdiff
path: root/lib/Checker/BasicStore.cpp
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2010-07-01 20:16:50 +0000
committerTed Kremenek <kremenek@apple.com>2010-07-01 20:16:50 +0000
commitdcee3ce97fc76f20ce8f5a7451071e3dec537073 (patch)
tree16e01fa048f6f6490552b2b1eea8f71bcf9b2aae /lib/Checker/BasicStore.cpp
parent7dadf79bd809cc01fe275f9a7243593bc2af5c10 (diff)
Fix PR 7475 by enhancing the static analyzer to also invalidate bindings for non-static global variables
when calling a function/method whose impact on global variables we cannot accurately estimate. This change introduces two new MemSpaceRegions that divide up the memory space of globals, and causes RegionStore and BasicStore to consult a binding to the NonStaticGlobalsMemSpaceRegion when lazily determining the value of a global. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@107423 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Checker/BasicStore.cpp')
-rw-r--r--lib/Checker/BasicStore.cpp90
1 files changed, 84 insertions, 6 deletions
diff --git a/lib/Checker/BasicStore.cpp b/lib/Checker/BasicStore.cpp
index e1c488d0d2..62c8d9c248 100644
--- a/lib/Checker/BasicStore.cpp
+++ b/lib/Checker/BasicStore.cpp
@@ -46,9 +46,14 @@ public:
SVal Retrieve(Store store, Loc loc, QualType T = QualType());
- Store InvalidateRegion(Store store, const MemRegion *R, const Expr *E,
+ Store 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);
+
Store scanForIvars(Stmt *B, const Decl* SelfDecl,
const MemRegion *SelfRegion, Store St);
@@ -73,8 +78,8 @@ public:
/// RemoveDeadBindings - Scans a BasicStore of 'state' for dead values.
/// It updatees the GRState object in place with the values removed.
const GRState *RemoveDeadBindings(GRState &state,
- const StackFrameContext *LCtx,
- SymbolReaper& SymReaper,
+ const StackFrameContext *LCtx,
+ SymbolReaper& SymReaper,
llvm::SmallVectorImpl<const MemRegion*>& RegionRoots);
void iterBindings(Store store, BindingsHandler& f);
@@ -144,9 +149,30 @@ SVal BasicStoreManager::LazyRetrieve(Store store, const TypedRegion *R) {
// Globals and parameters start with symbolic values.
// Local variables initially are undefined.
+
+ // Non-static globals may have had their values reset by InvalidateRegions.
+ const MemSpaceRegion *MS = VR->getMemorySpace();
+ if (isa<NonStaticGlobalSpaceRegion>(MS)) {
+ BindingsTy B = GetBindings(store);
+ // FIXME: Copy-and-pasted from RegionStore.cpp.
+ if (BindingsTy::data_type *Val = B.lookup(MS)) {
+ if (SymbolRef parentSym = Val->getAsSymbol())
+ return ValMgr.getDerivedRegionValueSymbolVal(parentSym, R);
+
+ if (Val->isZeroConstant())
+ return ValMgr.makeZeroVal(T);
+
+ if (Val->isUnknownOrUndef())
+ return *Val;
+
+ assert(0 && "Unknown default value.");
+ }
+ }
+
if (VR->hasGlobalsOrParametersStorage() ||
isa<UnknownSpaceRegion>(VR->getMemorySpace()))
return ValMgr.getRegionValueSymbolVal(R);
+
return UndefinedVal();
}
@@ -194,6 +220,14 @@ Store BasicStoreManager::Bind(Store store, Loc loc, SVal V) {
return store;
const MemRegion* R = cast<loc::MemRegionVal>(loc).getRegion();
+
+ // Special case: a default symbol assigned to the NonStaticGlobalsSpaceRegion
+ // that is used to derive other symbols.
+ if (isa<NonStaticGlobalSpaceRegion>(R)) {
+ BindingsTy B = GetBindings(store);
+ return VBFactory.Add(B, R, V).getRoot();
+ }
+
ASTContext &C = StateMgr.getContext();
// Special case: handle store of pointer values (Loc) to pointers via
@@ -268,9 +302,9 @@ const GRState *BasicStoreManager::RemoveDeadBindings(GRState &state,
else
continue;
}
- else if (isa<ObjCIvarRegion>(I.getKey())) {
+ else if (isa<ObjCIvarRegion>(I.getKey()) ||
+ isa<NonStaticGlobalSpaceRegion>(I.getKey()))
RegionRoots.push_back(I.getKey());
- }
else
continue;
@@ -292,7 +326,8 @@ const GRState *BasicStoreManager::RemoveDeadBindings(GRState &state,
SymReaper.markLive(SymR->getSymbol());
break;
}
- else if (isa<VarRegion>(MR) || isa<ObjCIvarRegion>(MR)) {
+ else if (isa<VarRegion>(MR) || isa<ObjCIvarRegion>(MR) ||
+ isa<NonStaticGlobalSpaceRegion>(MR)) {
if (Marked.count(MR))
break;
@@ -486,6 +521,49 @@ StoreManager::BindingsHandler::~BindingsHandler() {}
// Binding invalidation.
//===----------------------------------------------------------------------===//
+
+Store BasicStoreManager::InvalidateRegions(Store store,
+ const MemRegion * const *I,
+ const MemRegion * const *End,
+ const Expr *E, unsigned Count,
+ InvalidatedSymbols *IS,
+ bool invalidateGlobals) {
+ 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);
+ }
+ }
+
+ for ( ; I != End ; ++I) {
+ const MemRegion *R = *I;
+ // Don't invalidate globals twice.
+ if (invalidateGlobals) {
+ if (isa<NonStaticGlobalSpaceRegion>(R->getMemorySpace()))
+ continue;
+ }
+ store = InvalidateRegion(store, *I, E, Count, IS);
+ }
+
+ // FIXME: This is copy-and-paste from RegionStore.cpp.
+ if (invalidateGlobals) {
+ // Bind the non-static globals memory space to a new symbol that we will
+ // use to derive the bindings for all non-static globals.
+ const GlobalsSpaceRegion *GS = MRMgr.getGlobalsRegion();
+ SVal V =
+ ValMgr.getConjuredSymbolVal(/* SymbolTag = */ (void*) GS, E,
+ /* symbol type, doesn't matter */ Ctx.IntTy,
+ Count);
+
+ store = Bind(store, loc::MemRegionVal(GS), V);
+ }
+
+ return store;
+}
+
+
Store BasicStoreManager::InvalidateRegion(Store store,
const MemRegion *R,
const Expr *E,