forked from OSchip/llvm-project
Fix RegionStore bug when doing a field load whose parent is also a field assigned a LazyCompoundValue. Fixes <rdar://problem/9163742> and PR 9522.
llvm-svn: 128783
This commit is contained in:
parent
17bf4922c9
commit
850d35be16
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue