diff options
author | Ted Kremenek <kremenek@apple.com> | 2010-03-02 21:43:54 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2010-03-02 21:43:54 +0000 |
commit | 5ba290a12fb9390a77ea4dca3d98deb53022d182 (patch) | |
tree | 2e8f3deccfd293605355fb0f2192f88f88431c7f /lib/Checker/BasicStore.cpp | |
parent | a804a68f5a1ad739eb17ff2fd942d12abbc30b08 (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.cpp | 48 |
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; } |