Reapply most of r82939, but add a guard that FieldRegions and friends

are only specially treated by RegionStore::InvalidateRegion() when
their super region is also invalidated.  When this isn't the case,
conjure a new symbol for a FieldRegion.  Thanks to Zhongxing Xu and
Daniel Dunbar for pointing out this issue.

llvm-svn: 83043
This commit is contained in:
Ted Kremenek 2009-09-29 03:34:03 +00:00
parent 4d46522df1
commit 5daec8a834
2 changed files with 26 additions and 4 deletions

View File

@ -514,15 +514,20 @@ const GRState *RegionStoreManager::InvalidateRegion(const GRState *state,
continue;
}
// FIXME: Special case FieldRegion/ElementRegion for more
// efficient invalidation. We don't need to conjure symbols for
// these regions in all cases.
// Get the old binding. Is it a region? If so, add it to the worklist.
if (const SVal *OldV = B.lookup(R)) {
if (const MemRegion *RV = OldV->getAsRegion())
WorkList.push_back(RV);
}
if ((isa<FieldRegion>(R)||isa<ElementRegion>(R)||isa<ObjCIvarRegion>(R))
&& Visited[cast<SubRegion>(R)->getSuperRegion()]) {
// For fields and elements whose super region has also been invalidated,
// only remove the old binding. The super region will get set with a
// default value from which we can lazily derive a new symbolic value.
B = RBFactory.Remove(B, R);
continue;
}
// Invalidate the binding.
DefinedOrUnknownSVal V = ValMgr.getConjuredSymbolVal(R, Ex, T, Count);

View File

@ -249,3 +249,20 @@ int rdar_6914474(void) {
return x; // no-warning
}
// Test invalidation of a single field.
struct s_test_field_invalidate {
int x;
};
extern void test_invalidate_field(int *x);
int test_invalidate_field_test() {
struct s_test_field_invalidate y;
test_invalidate_field(&y.x);
return y.x; // no-warning
}
int test_invalidate_field_test_positive() {
struct s_test_field_invalidate y;
return y.x; // expected-warning{{garbage}}
}