diff options
author | Ted Kremenek <kremenek@apple.com> | 2011-04-03 04:09:15 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2011-04-03 04:09:15 +0000 |
commit | 45fa623886dfb6a23b3cfd6d8764e05884382180 (patch) | |
tree | f5c4c2b8c38b6b697266585345738f4d1d584df9 /lib/StaticAnalyzer/Core/RegionStore.cpp | |
parent | 2166948cc721b138b3aaf4358d28ec2dada22901 (diff) |
Fix RegionStore bug when doing a field load whose parent is also a field assigned a LazyCompoundValue. Fixes <rdar://problem/9163742> and PR 9522.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@128783 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/StaticAnalyzer/Core/RegionStore.cpp')
-rw-r--r-- | lib/StaticAnalyzer/Core/RegionStore.cpp | 28 |
1 files changed, 17 insertions, 11 deletions
diff --git a/lib/StaticAnalyzer/Core/RegionStore.cpp b/lib/StaticAnalyzer/Core/RegionStore.cpp index 0361595025..f14b8ad94f 100644 --- a/lib/StaticAnalyzer/Core/RegionStore.cpp +++ b/lib/StaticAnalyzer/Core/RegionStore.cpp @@ -358,7 +358,8 @@ public: // Part of public interface to class. /// Get the state and region whose binding this region R corresponds to. std::pair<Store, const MemRegion*> - GetLazyBinding(RegionBindings B, const MemRegion *R); + GetLazyBinding(RegionBindings B, const MemRegion *R, + const MemRegion *originalRegion); StoreRef CopyLazyBindings(nonloc::LazyCompoundVal V, Store store, const TypedRegion *R); @@ -979,10 +980,20 @@ SVal RegionStoreManager::Retrieve(Store store, Loc L, QualType T) { } std::pair<Store, const MemRegion *> -RegionStoreManager::GetLazyBinding(RegionBindings B, const MemRegion *R) { +RegionStoreManager::GetLazyBinding(RegionBindings B, const MemRegion *R, + const MemRegion *originalRegion) { + + if (originalRegion != R) { + if (Optional<SVal> OV = getDefaultBinding(B, R)) { + if (const nonloc::LazyCompoundVal *V = + dyn_cast<nonloc::LazyCompoundVal>(OV.getPointer())) + return std::make_pair(V->getStore(), V->getRegion()); + } + } + if (const ElementRegion *ER = dyn_cast<ElementRegion>(R)) { const std::pair<Store, const MemRegion *> &X = - GetLazyBinding(B, ER->getSuperRegion()); + GetLazyBinding(B, ER->getSuperRegion(), originalRegion); if (X.second) return std::make_pair(X.first, @@ -990,7 +1001,7 @@ RegionStoreManager::GetLazyBinding(RegionBindings B, const MemRegion *R) { } else if (const FieldRegion *FR = dyn_cast<FieldRegion>(R)) { const std::pair<Store, const MemRegion *> &X = - GetLazyBinding(B, FR->getSuperRegion()); + GetLazyBinding(B, FR->getSuperRegion(), originalRegion); if (X.second) return std::make_pair(X.first, @@ -1001,17 +1012,12 @@ RegionStoreManager::GetLazyBinding(RegionBindings B, const MemRegion *R) { else if (const CXXBaseObjectRegion *baseReg = dyn_cast<CXXBaseObjectRegion>(R)) { const std::pair<Store, const MemRegion *> &X = - GetLazyBinding(B, baseReg->getSuperRegion()); + GetLazyBinding(B, baseReg->getSuperRegion(), originalRegion); if (X.second) return std::make_pair(X.first, MRMgr.getCXXBaseObjectRegionWithSuper(baseReg, X.second)); } - else if (Optional<SVal> OV = getDefaultBinding(B, R)) { - if (const nonloc::LazyCompoundVal *V = - dyn_cast<nonloc::LazyCompoundVal>(OV.getPointer())) - return std::make_pair(V->getStore(), V->getRegion()); - } // The NULL MemRegion indicates an non-existent lazy binding. A NULL Store is // possible for a valid lazy binding. @@ -1158,7 +1164,7 @@ SVal RegionStoreManager::RetrieveFieldOrElementCommon(Store store, // Lazy binding? Store lazyBindingStore = NULL; const MemRegion *lazyBindingRegion = NULL; - llvm::tie(lazyBindingStore, lazyBindingRegion) = GetLazyBinding(B, R); + llvm::tie(lazyBindingStore, lazyBindingRegion) = GetLazyBinding(B, R, R); if (lazyBindingRegion) return RetrieveLazyBinding(lazyBindingRegion, lazyBindingStore); |