Enhance RegionStore::InvalidateRegions() to correctly invalidate bindings

by scanning through the values of LazyCompoundVals.

llvm-svn: 96067
This commit is contained in:
Ted Kremenek 2010-02-13 01:52:33 +00:00
parent 492b8b42cd
commit 1a6672a3d4
2 changed files with 63 additions and 12 deletions

View File

@ -475,17 +475,19 @@ class InvalidateRegionsWorker {
ClusterMap ClusterM;
WorkList WL;
RegionStoreManager &RM;
StoreManager::InvalidatedSymbols *IS;
ASTContext &Ctx;
ValueManager &ValMgr;
public:
InvalidateRegionsWorker(StoreManager::InvalidatedSymbols *is,
InvalidateRegionsWorker(RegionStoreManager &rm,
StoreManager::InvalidatedSymbols *is,
ASTContext &ctx, ValueManager &valMgr)
: IS(is), Ctx(ctx), ValMgr(valMgr) {}
: RM(rm), IS(is), Ctx(ctx), ValMgr(valMgr) {}
Store InvalidateRegions(RegionStoreManager &RM, Store store,
const MemRegion * const *I,const MemRegion * const *E,
Store InvalidateRegions(Store store, const MemRegion * const *I,
const MemRegion * const *E,
const Expr *Ex, unsigned Count);
private:
@ -529,17 +531,34 @@ InvalidateRegionsWorker::getCluster(const MemRegion *R) {
}
void InvalidateRegionsWorker::VisitBinding(SVal V) {
if (const MemRegion *R = V.getAsRegion())
AddToWorkList(R);
// A symbol? Mark it touched by the invalidation.
if (IS)
if (SymbolRef Sym = V.getAsSymbol())
IS->insert(Sym);
}
Store InvalidateRegionsWorker::InvalidateRegions(RegionStoreManager &RM,
Store store,
if (const MemRegion *R = V.getAsRegion()) {
AddToWorkList(R);
return;
}
// Is it a LazyCompoundVal? All references get invalidated as well.
if (const nonloc::LazyCompoundVal *LCS =
dyn_cast<nonloc::LazyCompoundVal>(&V)) {
const MemRegion *LazyR = LCS->getRegion();
RegionBindings B = RegionStoreManager::GetRegionBindings(LCS->getStore());
for (RegionBindings::iterator RI = B.begin(), RE = B.end(); RI != RE; ++RI){
const MemRegion *baseR = RI.getKey().getRegion();
if (cast<SubRegion>(baseR)->isSubRegionOf(LazyR))
VisitBinding(RI.getData());
}
return;
}
}
Store InvalidateRegionsWorker::InvalidateRegions(Store store,
const MemRegion * const *I,
const MemRegion * const *E,
const Expr *Ex, unsigned Count)
@ -652,8 +671,9 @@ Store RegionStoreManager::InvalidateRegions(Store store,
const MemRegion * const *E,
const Expr *Ex, unsigned Count,
InvalidatedSymbols *IS) {
InvalidateRegionsWorker W(IS, getContext(), StateMgr.getValueManager());
return W.InvalidateRegions(*this, store, I, E, Ex, Count);
InvalidateRegionsWorker W(*this, IS, getContext(),
StateMgr.getValueManager());
return W.InvalidateRegions(store, I, E, Ex, Count);
}
//===----------------------------------------------------------------------===//

View File

@ -836,3 +836,34 @@ int PR4172B_f1(void) {
return x; // no-warning
}
//===----------------------------------------------------------------------===//
// Test invalidation of values in struct literals.
//===----------------------------------------------------------------------===//
struct s_rev96062 { int *x; int *y; };
struct s_rev96062_nested { struct s_rev96062 z; };
void test_a_rev96062_aux(struct s_rev96062 *s);
void test_a_rev96062_aux2(struct s_rev96062_nested *s);
int test_a_rev96062() {
int a, b;
struct s_rev96062 x = { &a, &b };
test_a_rev96062_aux(&x);
return a + b; // no-warning
}
int test_b_rev96062() {
int a, b;
struct s_rev96062 x = { &a, &b };
struct s_rev96062 z = x;
test_a_rev96062_aux(&z);
return a + b; // no-warning
}
int test_c_rev96062() {
int a, b;
struct s_rev96062 x = { &a, &b };
struct s_rev96062_nested w = { x };
struct s_rev96062_nested z = w;
test_a_rev96062_aux2(&z);
return a + b; // no-warning
}