]> granicus.if.org Git - clang/commitdiff
Implement FIXME: GRStateManager::scanReachableSymbols now supports scanning MemRegions.
authorTed Kremenek <kremenek@apple.com>
Tue, 3 Mar 2009 02:51:43 +0000 (02:51 +0000)
committerTed Kremenek <kremenek@apple.com>
Tue, 3 Mar 2009 02:51:43 +0000 (02:51 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@65919 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Analysis/PathSensitive/Environment.h
include/clang/Analysis/PathSensitive/GRState.h
include/clang/Analysis/PathSensitive/Store.h
lib/Analysis/BasicStore.cpp
lib/Analysis/Environment.cpp
lib/Analysis/GRState.cpp
lib/Analysis/RegionStore.cpp

index 5c702d659c360e70463e610d1f728b8d1f421587..fde8b167f3c759f7c1c55659af80b18e208df294 100644 (file)
@@ -141,7 +141,7 @@ public:
 
   Environment
   RemoveDeadBindings(Environment Env, Stmt* Loc, SymbolReaper& SymReaper,
-                     GRStateManager& StateMgr,
+                     GRStateManager& StateMgr, const GRState *state,
                      llvm::SmallVectorImpl<const MemRegion*>& DRoots);
 
 };
index 18cba5dc0d8c012a91b3730e51cd702f31856d46..ac474edfdf53d756d93dae4b7b6eca48bc246045 100644 (file)
@@ -611,8 +611,8 @@ public:
     ConstraintMgr->EndPath(St);
   }
 
-  bool scanReachableSymbols(nonloc::CompoundVal val, SymbolVisitor& vistor);
-  bool scanReachableSymbols(SVal val, SymbolVisitor& visitor);
+  bool scanReachableSymbols(SVal val, const GRState* state,
+                            SymbolVisitor& visitor);
 };
   
 //===----------------------------------------------------------------------===//
@@ -738,7 +738,7 @@ public:
   template <typename CB>
   CB scanReachableSymbols(SVal val) {
     CB cb(*this);
-    Mgr->scanReachableSymbols(val, cb);
+    Mgr->scanReachableSymbols(val, St, cb);
     return cb;
   }
   
index 2f7920ac6b5c8978651569650b74546ece3e8bf0..ac0625dd01995144df9d08aa7f8ff7649f0bb8fa 100644 (file)
@@ -170,11 +170,11 @@ public:
   
   class Visitor {
   public:
-    virtual ~Visitor() {}
-    virtual bool Visit(const MemRegion* Parent, const MemRegion* SubRegion);    
+    virtual ~Visitor() {};
+    virtual bool Visit(const MemRegion* Parent, const MemRegion* SubRegion) = 0;
   };
   
-  virtual void iterSubRegions(const MemRegion* R, Visitor& V) const = 0;  
+  virtual bool iterSubRegions(const MemRegion* R, Visitor& V) const = 0;  
 };
   
 StoreManager* CreateBasicStoreManager(GRStateManager& StMgr);
index 31408c02445f29a9564efc84916c2113009aff6b..35c6652fe58b80b0f398d0a12cbda3eeebdb7c25 100644 (file)
@@ -27,8 +27,9 @@ class VISIBILITY_HIDDEN BasicStoreSubRegionMap : public SubRegionMap {
 public:
   BasicStoreSubRegionMap() {}
 
-  void iterSubRegions(const MemRegion* R, Visitor& V) const {
+  bool iterSubRegions(const MemRegion* R, Visitor& V) const {
     // Do nothing.  No subregions.
+    return true;
   }
 };
   
index e3ed678d5e95926de41a2231d5e6b9ffdba1981d..41adddc360b23ff63bd13949761fe113af2ebee7 100644 (file)
@@ -119,6 +119,7 @@ Environment
 EnvironmentManager::RemoveDeadBindings(Environment Env, Stmt* Loc,
                                        SymbolReaper& SymReaper,
                                        GRStateManager& StateMgr,
+                                       const GRState *state,
                               llvm::SmallVectorImpl<const MemRegion*>& DRoots) {
   
   // Drop bindings for subexpressions.
@@ -138,7 +139,7 @@ EnvironmentManager::RemoveDeadBindings(Environment Env, Stmt* Loc,
 
       // Mark all symbols in the block expr's value live.
       MarkLiveCallback cb(SymReaper);
-      StateMgr.scanReachableSymbols(X, cb);
+      StateMgr.scanReachableSymbols(X, state, cb);
     } else {
       // The block expr is dead.
       SVal X = I.getData();
index 0788b432ba5e91b00bf9cac1c4eb344e52504070..794871cb1a73efd50b6b45828cac9e31b6bb6f98 100644 (file)
@@ -46,7 +46,7 @@ GRStateManager::RemoveDeadBindings(const GRState* state, Stmt* Loc,
   GRState NewState = *state;
 
   NewState.Env = EnvMgr.RemoveDeadBindings(NewState.Env, Loc, SymReaper, *this,
-                                           RegionRoots);
+                                           state, RegionRoots);
 
   // Clean up the store.
   NewState.St = StoreMgr->RemoveDeadBindings(&NewState, Loc, SymReaper,
@@ -208,19 +208,42 @@ const GRState* GRStateManager::addGDM(const GRState* St, void* Key, void* Data){
 // Utility.
 //===----------------------------------------------------------------------===//
 
-bool GRStateManager::scanReachableSymbols(nonloc::CompoundVal val,
-                                          SymbolVisitor& visitor) {
+namespace {
+  class VISIBILITY_HIDDEN ScanReachableSymbols : public SubRegionMap::Visitor  {
+  typedef llvm::DenseSet<const MemRegion*> VisitedRegionsTy;
+
+  VisitedRegionsTy visited;
+  GRStateRef state;
+  SymbolVisitor &visitor;
+  llvm::OwningPtr<SubRegionMap> SRM;
+public:
+  
+  ScanReachableSymbols(GRStateManager* sm, const GRState *st, SymbolVisitor& v)
+    : state(st, *sm), visitor(v) {}
+  
+  bool scan(nonloc::CompoundVal val);
+  bool scan(SVal val);
+  bool scan(const MemRegion *R);
+    
+  // From SubRegionMap::Visitor.
+  bool Visit(const MemRegion* Parent, const MemRegion* SubRegion) {
+    return scan(SubRegion);
+  }
+};
+}
+
+bool ScanReachableSymbols::scan(nonloc::CompoundVal val) {
   for (nonloc::CompoundVal::iterator I=val.begin(), E=val.end(); I!=E; ++I)
-    if (!scanReachableSymbols(*I, visitor)) return false;
+    if (!scan(*I))
+      return false;
 
   return true;
 }
-
-bool GRStateManager::scanReachableSymbols(SVal val, SymbolVisitor& visitor) {
-  
-  // FIXME: Scan through through the reachable regions.
-  // if (isa<Loc>(val)) { ... }
-  
+    
+bool ScanReachableSymbols::scan(SVal val) {
+  if (loc::MemRegionVal *X = dyn_cast<loc::MemRegionVal>(&val))
+    return scan(X->getRegion());
+    
   if (loc::SymbolVal *X = dyn_cast<loc::SymbolVal>(&val))
     return visitor.VisitSymbol(X->getSymbol());
   
@@ -228,10 +251,43 @@ bool GRStateManager::scanReachableSymbols(SVal val, SymbolVisitor& visitor) {
     return visitor.VisitSymbol(X->getSymbol());
   
   if (nonloc::CompoundVal *X = dyn_cast<nonloc::CompoundVal>(&val))
-    return scanReachableSymbols(*X, visitor);
+    return scan(*X);
   
   return true;
 }
+  
+bool ScanReachableSymbols::scan(const MemRegion *R) {
+  if (visited.count(R))
+    return true;
+  
+  visited.insert(R);
+
+  // If this is a symbolic region, visit the symbol for the region.
+  if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(R))
+    if (!visitor.VisitSymbol(SR->getSymbol()))
+      return false;
+  
+  // If this is a subregion, also visit the parent regions.
+  if (const SubRegion *SR = dyn_cast<SubRegion>(R))
+    if (!scan(SR->getSuperRegion()));
+      return false;
+  
+  // Now look at the binding to this region (if any).
+  if (!scan(state.GetSVal(R)))
+    return false;
+  
+  // Now look at the subregions.
+  if (!SRM.get())
+   SRM.reset(state.getManager().getStoreManager().getSubRegionMap(state).get());
+  
+  return SRM->iterSubRegions(R, *this);
+}
+
+bool GRStateManager::scanReachableSymbols(SVal val, const GRState* state,
+                                          SymbolVisitor& visitor) {
+  ScanReachableSymbols S(this, state, visitor);
+  return S.scan(val);
+}
 
 //===----------------------------------------------------------------------===//
 // Queries.
index 0671a806d2200d2a6a33fd16e528f7d90db97b67..6238ff20ed7a9a0d12ce12fbbb335abc377092c6 100644 (file)
@@ -121,18 +121,20 @@ public:
     
   ~RegionStoreSubRegionMap() {}
   
-  void iterSubRegions(const MemRegion* Parent, Visitor& V) const {
+  bool iterSubRegions(const MemRegion* Parent, Visitor& V) const {
     Map::iterator I = M.find(Parent);
 
     if (I == M.end())
-      return;
+      return true;
     
     llvm::ImmutableSet<const MemRegion*> S = I->second;
     for (llvm::ImmutableSet<const MemRegion*>::iterator SI=S.begin(),SE=S.end();
          SI != SE; ++SI) {
       if (!V.Visit(Parent, *SI))
-        return;
+        return false;
     }
+    
+    return true;
   }
 };  
 
@@ -600,10 +602,8 @@ RegionStoreManager::CastRegion(const GRState* state, const MemRegion* R,
 
 SVal RegionStoreManager::EvalBinOp(BinaryOperator::Opcode Op, Loc L, NonLoc R) {
   // Assume the base location is MemRegionVal(ElementRegion).
-
-  if (!isa<loc::MemRegionVal>(L)) {
+  if (!isa<loc::MemRegionVal>(L))
     return UnknownVal();
-  }
 
   const MemRegion* MR = cast<loc::MemRegionVal>(L).getRegion();
 
@@ -621,8 +621,9 @@ SVal RegionStoreManager::EvalBinOp(BinaryOperator::Opcode Op, Loc L, NonLoc R) {
                                                     ER->getArrayRegion());
     return Loc::MakeVal(NewER);
 
-  } else
-    return UnknownVal();
+  }
+  
+  return UnknownVal();
 }
 
 SVal RegionStoreManager::Retrieve(const GRState* St, Loc L, QualType T) {