aboutsummaryrefslogtreecommitdiff
path: root/lib/Checker/BasicStore.cpp
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2010-03-02 21:43:54 +0000
committerTed Kremenek <kremenek@apple.com>2010-03-02 21:43:54 +0000
commit5ba290a12fb9390a77ea4dca3d98deb53022d182 (patch)
tree2e8f3deccfd293605355fb0f2192f88f88431c7f /lib/Checker/BasicStore.cpp
parenta804a68f5a1ad739eb17ff2fd942d12abbc30b08 (diff)
[CFG]
After discussion with Zhongxing, don't force the initializer of DeclStmts to be block-level expressions. This led to some interesting fallout: [UninitializedValues] Always visit the initializer of DeclStmts (do not assume they are block-level expressions). [BasicStore] With initializers of DeclStmts no longer block-level expressions, this causes self-referencing initializers (e.g. 'int x = x') to no longer cause the initialized variable to be live before the DeclStmt. While this is correct, it caused BasicStore::RemoveDeadBindings() to prune off the values of these variables from the initial store (where they are set to uninitialized). The fix is to back-port some (and only some) of the lazy-binding logic from RegionStore to BasicStore. Now the default values of local variables are determined lazily as opposed to explicitly initialized. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@97591 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Checker/BasicStore.cpp')
-rw-r--r--lib/Checker/BasicStore.cpp48
1 files changed, 29 insertions, 19 deletions
diff --git a/lib/Checker/BasicStore.cpp b/lib/Checker/BasicStore.cpp
index 3661ae18fa..d93a6658c6 100644
--- a/lib/Checker/BasicStore.cpp
+++ b/lib/Checker/BasicStore.cpp
@@ -95,6 +95,8 @@ public:
const char *sep);
private:
+ SVal LazyRetrieve(Store store, const TypedRegion *R);
+
ASTContext& getContext() { return StateMgr.getContext(); }
};
@@ -126,6 +128,25 @@ static bool isHigherOrderRawPtr(QualType T, ASTContext &C) {
}
}
+SVal BasicStoreManager::LazyRetrieve(Store store, const TypedRegion *R) {
+ const VarRegion *VR = dyn_cast<VarRegion>(R);
+ if (!VR)
+ return UnknownVal();
+
+ const VarDecl *VD = VR->getDecl();
+ QualType T = VD->getType();
+
+ // Only handle simple types that we can symbolicate.
+ if (!SymbolManager::canSymbolicate(T) || !T->isScalarType())
+ return UnknownVal();
+
+ // Globals and parameters start with symbolic values.
+ // Local variables initially are undefined.
+ if (VR->hasGlobalsOrParametersStorage())
+ return ValMgr.getRegionValueSymbolVal(R);
+ return UndefinedVal();
+}
+
SVal BasicStoreManager::Retrieve(Store store, Loc loc, QualType T) {
if (isa<UnknownVal>(loc))
return UnknownVal();
@@ -142,11 +163,13 @@ SVal BasicStoreManager::Retrieve(Store store, Loc loc, QualType T) {
BindingsTy B = GetBindings(store);
BindingsTy::data_type *Val = B.lookup(R);
+ const TypedRegion *TR = cast<TypedRegion>(R);
- if (!Val)
- break;
+ if (Val)
+ return CastRetrievedVal(*Val, TR, T);
- return CastRetrievedVal(*Val, cast<TypedRegion>(R), T);
+ SVal V = LazyRetrieve(store, TR);
+ return V.isUnknownOrUndef() ? V : CastRetrievedVal(V, TR, T);
}
case loc::ConcreteIntKind:
@@ -353,8 +376,8 @@ Store BasicStoreManager::getInitialStore(const LocationContext *InitLoc) {
// SelfRegion? (i.e., it implements MD->getClassInterface()).
const VarRegion *VR = MRMgr.getVarRegion(PD, InitLoc);
const MemRegion *SelfRegion =
- ValMgr.getRegionValueSymbolVal(VR).getAsRegion();
- assert(SelfRegion);
+ ValMgr.getRegionValueSymbolVal(VR).getAsRegion();
+ assert(SelfRegion);
St = Bind(St, ValMgr.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.
@@ -362,21 +385,8 @@ Store BasicStoreManager::getInitialStore(const LocationContext *InitLoc) {
}
}
}
- else if (VarDecl* VD = dyn_cast<VarDecl>(ND)) {
- // Only handle simple types that we can symbolicate.
- if (!SymbolManager::canSymbolicate(VD->getType()))
- continue;
-
- // Initialize globals and parameters to symbolic values.
- // Initialize local variables to undefined.
- const VarRegion *R = ValMgr.getRegionManager().getVarRegion(VD, InitLoc);
- SVal X = UndefinedVal();
- if (R->hasGlobalsOrParametersStorage())
- X = ValMgr.getRegionValueSymbolVal(R);
-
- St = Bind(St, ValMgr.makeLoc(R), X);
- }
}
+
return St;
}