Added GRStateManager::scanReachableSymbols(), a method which scans the reachable
symbols from an SVal.

- Fixed a bug in EnvironmentManager::RemoveDeadBindings() where it did not mark
  live all the symbols reachable from a live block-level expression.

- Fixed a bug in the retain/release checker where it did not stop tracking
  symbols that 'escaped' via compound literals being assigned to something the
  BasicStoreManager didn't reason about.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@64534 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Analysis/GRState.cpp b/lib/Analysis/GRState.cpp
index ea6f7a0..0788b43 100644
--- a/lib/Analysis/GRState.cpp
+++ b/lib/Analysis/GRState.cpp
@@ -45,7 +45,7 @@
   llvm::SmallVector<const MemRegion*, 10> RegionRoots;
   GRState NewState = *state;
 
-  NewState.Env = EnvMgr.RemoveDeadBindings(NewState.Env, Loc, SymReaper,
+  NewState.Env = EnvMgr.RemoveDeadBindings(NewState.Env, Loc, SymReaper, *this,
                                            RegionRoots);
 
   // Clean up the store.
@@ -205,6 +205,35 @@
 }
 
 //===----------------------------------------------------------------------===//
+// Utility.
+//===----------------------------------------------------------------------===//
+
+bool GRStateManager::scanReachableSymbols(nonloc::CompoundVal val,
+                                          SymbolVisitor& visitor) {
+  for (nonloc::CompoundVal::iterator I=val.begin(), E=val.end(); I!=E; ++I)
+    if (!scanReachableSymbols(*I, visitor)) return false;
+
+  return true;
+}
+
+bool GRStateManager::scanReachableSymbols(SVal val, SymbolVisitor& visitor) {
+  
+  // FIXME: Scan through through the reachable regions.
+  // if (isa<Loc>(val)) { ... }
+  
+  if (loc::SymbolVal *X = dyn_cast<loc::SymbolVal>(&val))
+    return visitor.VisitSymbol(X->getSymbol());
+  
+  if (nonloc::SymbolVal *X = dyn_cast<nonloc::SymbolVal>(&val))
+    return visitor.VisitSymbol(X->getSymbol());
+  
+  if (nonloc::CompoundVal *X = dyn_cast<nonloc::CompoundVal>(&val))
+    return scanReachableSymbols(*X, visitor);
+  
+  return true;
+}
+
+//===----------------------------------------------------------------------===//
 // Queries.
 //===----------------------------------------------------------------------===//