aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/StaticAnalyzer/RegionStore.cpp29
1 files changed, 27 insertions, 2 deletions
diff --git a/lib/StaticAnalyzer/RegionStore.cpp b/lib/StaticAnalyzer/RegionStore.cpp
index def1b43f34..e47a77e6fc 100644
--- a/lib/StaticAnalyzer/RegionStore.cpp
+++ b/lib/StaticAnalyzer/RegionStore.cpp
@@ -1572,13 +1572,38 @@ Store RegionStoreManager::BindStruct(Store store, const TypedRegion* R,
Store RegionStoreManager::KillStruct(Store store, const TypedRegion* R,
SVal DefaultVal) {
+
+ BindingKey key = BindingKey::Make(R, BindingKey::Default);
+
+ // The BindingKey may be "invalid" if we cannot handle the region binding
+ // explicitly. One example is something like array[index], where index
+ // is a symbolic value. In such cases, we want to invalidate the entire
+ // array, as the index assignment could have been to any element. In
+ // the case of nested symbolic indices, we need to march up the region
+ // hierarchy untile we reach a region whose binding we can reason about.
+ const SubRegion *subReg = R;
+
+ while (!key.isValid()) {
+ if (const SubRegion *tmp = dyn_cast<SubRegion>(subReg->getSuperRegion())) {
+ subReg = tmp;
+ key = BindingKey::Make(tmp, BindingKey::Default);
+ }
+ else
+ break;
+ }
+
+ // Remove the old bindings, using 'subReg' as the root of all regions
+ // we will invalidate.
RegionBindings B = GetRegionBindings(store);
llvm::OwningPtr<RegionStoreSubRegionMap>
SubRegions(getRegionStoreSubRegionMap(store));
- RemoveSubRegionBindings(B, R, *SubRegions);
+ RemoveSubRegionBindings(B, subReg, *SubRegions);
// Set the default value of the struct region to "unknown".
- return addBinding(B, R, BindingKey::Default, DefaultVal).getRoot();
+ if (!key.isValid())
+ return B.getRoot();
+
+ return addBinding(B, key, DefaultVal).getRoot();
}
Store RegionStoreManager::CopyLazyBindings(nonloc::LazyCompoundVal V,