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,
rdar_8642434_funcA(y); // expected-warning{{Null pointer passed as an argument to a 'nonnull' parameter}}
}
+// <rdar://problem/8848957> - Handle loads and stores from a symbolic index
+// into array without warning about an uninitialized value being returned.
+// While RegionStore can't fully reason about this example, it shouldn't
+// warn here either.
+typedef struct s_test_rdar8848957 {
+ int x, y, z;
+} s_test_rdar8848957;
+
+s_test_rdar8848957 foo_rdar8848957();
+int rdar8848957(int index) {
+ s_test_rdar8848957 vals[10];
+ vals[index] = foo_rdar8848957();
+ return vals[index].x; // no-warning
+}