Fix another false positive in RegionStore involving doing loads from symbolic offsets. We still don't
properly reason about such accesses, but we shouldn't emit bogus "uninitialized value" warnings either. Fixes <rdar://problem/11127008>. llvm-svn: 153913
This commit is contained in:
parent
b495562b5d
commit
b75f4e5e9b
|
@ -1194,14 +1194,23 @@ SVal RegionStoreManager::getBindingForFieldOrElementCommon(Store store,
|
|||
|
||||
// At this point we have already checked in either getBindingForElement or
|
||||
// getBindingForField if 'R' has a direct binding.
|
||||
|
||||
RegionBindings B = GetRegionBindings(store);
|
||||
|
||||
// Record whether or not we see a symbolic index. That can completely
|
||||
// be out of scope of our lookup.
|
||||
bool hasSymbolicIndex = false;
|
||||
|
||||
while (superR) {
|
||||
if (const Optional<SVal> &D =
|
||||
getBindingForDerivedDefaultValue(B, superR, R, Ty))
|
||||
return *D;
|
||||
|
||||
if (const ElementRegion *ER = dyn_cast<ElementRegion>(superR)) {
|
||||
NonLoc index = ER->getIndex();
|
||||
if (!index.isConstant())
|
||||
hasSymbolicIndex = true;
|
||||
}
|
||||
|
||||
// If our super region is a field or element itself, walk up the region
|
||||
// hierarchy to see if there is a default value installed in an ancestor.
|
||||
if (const SubRegion *SR = dyn_cast<SubRegion>(superR)) {
|
||||
|
@ -1220,7 +1229,7 @@ SVal RegionStoreManager::getBindingForFieldOrElementCommon(Store store,
|
|||
return getLazyBinding(lazyBindingRegion, lazyBindingStore);
|
||||
|
||||
if (R->hasStackNonParametersStorage()) {
|
||||
if (const ElementRegion *ER = dyn_cast<ElementRegion>(R)) {
|
||||
if (isa<ElementRegion>(R)) {
|
||||
// Currently we don't reason specially about Clang-style vectors. Check
|
||||
// if superR is a vector and if so return Unknown.
|
||||
if (const TypedValueRegion *typedSuperR =
|
||||
|
@ -1228,13 +1237,15 @@ SVal RegionStoreManager::getBindingForFieldOrElementCommon(Store store,
|
|||
if (typedSuperR->getValueType()->isVectorType())
|
||||
return UnknownVal();
|
||||
}
|
||||
|
||||
// FIXME: We also need to take ElementRegions with symbolic indexes into
|
||||
// account.
|
||||
if (!ER->getIndex().isConstant())
|
||||
return UnknownVal();
|
||||
}
|
||||
|
||||
// FIXME: We also need to take ElementRegions with symbolic indexes into
|
||||
// account. This case handles both directly accessing an ElementRegion
|
||||
// with a symbolic offset, but also fields within an element with
|
||||
// a symbolic offset.
|
||||
if (hasSymbolicIndex)
|
||||
return UnknownVal();
|
||||
|
||||
return UndefinedVal();
|
||||
}
|
||||
|
||||
|
|
|
@ -1325,3 +1325,19 @@ void rdar9444714() {
|
|||
*dst = '\0';
|
||||
}
|
||||
|
||||
// Test handling symbolic elements with field accesses.
|
||||
// <rdar://problem/11127008>
|
||||
typedef struct {
|
||||
unsigned value;
|
||||
} RDar11127008;
|
||||
|
||||
signed rdar_11127008_index();
|
||||
|
||||
static unsigned rdar_11127008(void) {
|
||||
RDar11127008 values[] = {{.value = 0}, {.value = 1}};
|
||||
signed index = rdar_11127008_index();
|
||||
if (index < 0) return 0;
|
||||
if (index >= 2) return 0;
|
||||
return values[index].value;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue