diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/StaticAnalyzer/RegionStore.cpp | 29 |
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, |