From: Ted Kremenek Date: Sat, 13 Feb 2010 01:52:33 +0000 (+0000) Subject: Enhance RegionStore::InvalidateRegions() to correctly invalidate bindings X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=24c37ad067320e9d40978d97a73e4bca0f0eae54;p=clang Enhance RegionStore::InvalidateRegions() to correctly invalidate bindings by scanning through the values of LazyCompoundVals. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@96067 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Checker/RegionStore.cpp b/lib/Checker/RegionStore.cpp index ed1737cddb..f70105af13 100644 --- a/lib/Checker/RegionStore.cpp +++ b/lib/Checker/RegionStore.cpp @@ -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(&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(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); } //===----------------------------------------------------------------------===// diff --git a/test/Analysis/misc-ps-region-store.m b/test/Analysis/misc-ps-region-store.m index 46a8720c19..201cbc9b35 100644 --- a/test/Analysis/misc-ps-region-store.m +++ b/test/Analysis/misc-ps-region-store.m @@ -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 +}