diff options
author | Ted Kremenek <kremenek@apple.com> | 2012-04-03 00:03:34 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2012-04-03 00:03:34 +0000 |
commit | 31b57628576a2355428fd4b57f828a3aa8423000 (patch) | |
tree | 2f1b49c646690f55f31c1b981ca1744974b41cb9 | |
parent | d9b795524eb3dc035523f82f135d0a8adf15cd72 (diff) |
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>.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@153913 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/StaticAnalyzer/Core/RegionStore.cpp | 25 | ||||
-rw-r--r-- | test/Analysis/misc-ps-region-store.m | 16 |
2 files changed, 34 insertions, 7 deletions
diff --git a/lib/StaticAnalyzer/Core/RegionStore.cpp b/lib/StaticAnalyzer/Core/RegionStore.cpp index 4cafddc08a..1619e6bc64 100644 --- a/lib/StaticAnalyzer/Core/RegionStore.cpp +++ b/lib/StaticAnalyzer/Core/RegionStore.cpp @@ -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(); } diff --git a/test/Analysis/misc-ps-region-store.m b/test/Analysis/misc-ps-region-store.m index 7268c909be..1c5b0b29dd 100644 --- a/test/Analysis/misc-ps-region-store.m +++ b/test/Analysis/misc-ps-region-store.m @@ -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; +} + |