From: Ted Kremenek Date: Sun, 3 Apr 2011 04:09:15 +0000 (+0000) Subject: Fix RegionStore bug when doing a field load whose parent is also a field assigned... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=45fa623886dfb6a23b3cfd6d8764e05884382180;p=clang Fix RegionStore bug when doing a field load whose parent is also a field assigned a LazyCompoundValue. Fixes and PR 9522. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@128783 91177308-0d34-0410-b5e6-96231b3b80d8 --- 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 - 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 -RegionStoreManager::GetLazyBinding(RegionBindings B, const MemRegion *R) { +RegionStoreManager::GetLazyBinding(RegionBindings B, const MemRegion *R, + const MemRegion *originalRegion) { + + if (originalRegion != R) { + if (Optional OV = getDefaultBinding(B, R)) { + if (const nonloc::LazyCompoundVal *V = + dyn_cast(OV.getPointer())) + return std::make_pair(V->getStore(), V->getRegion()); + } + } + if (const ElementRegion *ER = dyn_cast(R)) { const std::pair &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(R)) { const std::pair &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(R)) { const std::pair &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 OV = getDefaultBinding(B, R)) { - if (const nonloc::LazyCompoundVal *V = - dyn_cast(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); diff --git a/test/Analysis/misc-ps-region-store.m b/test/Analysis/misc-ps-region-store.m index 46446af0bc..be0356d176 100644 --- a/test/Analysis/misc-ps-region-store.m +++ b/test/Analysis/misc-ps-region-store.m @@ -1274,3 +1274,28 @@ int PR9455_2() { return 1; } +// Test initialization of substructs via lazy compound values. +typedef float RDar9163742_Float; + +typedef struct { + RDar9163742_Float x, y; +} RDar9163742_Point; +typedef struct { + RDar9163742_Float width, height; +} RDar9163742_Size; +typedef struct { + RDar9163742_Point origin; + RDar9163742_Size size; +} RDar9163742_Rect; + +extern RDar9163742_Rect RDar9163742_RectIntegral(RDar9163742_Rect); + +RDar9163742_Rect RDar9163742_IntegralRect(RDar9163742_Rect frame) +{ + RDar9163742_Rect integralFrame; + integralFrame.origin.x = frame.origin.x; + integralFrame.origin.y = frame.origin.y; + integralFrame.size = frame.size; + return RDar9163742_RectIntegral(integralFrame); // no-warning; all fields initialized +} +