]> granicus.if.org Git - clang/commitdiff
Enhance RegionStore::InvalidateRegions() to correctly invalidate bindings
authorTed Kremenek <kremenek@apple.com>
Sat, 13 Feb 2010 01:52:33 +0000 (01:52 +0000)
committerTed Kremenek <kremenek@apple.com>
Sat, 13 Feb 2010 01:52:33 +0000 (01:52 +0000)
by scanning through the values of LazyCompoundVals.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@96067 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Checker/RegionStore.cpp
test/Analysis/misc-ps-region-store.m

index ed1737cddb0ba81f900e7c3fc647bcffba75c5f7..f70105af137997223a50eedc1ad26368ab8ca5c4 100644 (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);
 }
   
 //===----------------------------------------------------------------------===//
index 46a8720c19a7976640d612d02230253823216de9..201cbc9b350fb91351642771edfe8dd4fb90dd13 100644 (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
+}