]> granicus.if.org Git - clang/commitdiff
MemRegions:
authorTed Kremenek <kremenek@apple.com>
Tue, 23 Jun 2009 00:46:41 +0000 (00:46 +0000)
committerTed Kremenek <kremenek@apple.com>
Tue, 23 Jun 2009 00:46:41 +0000 (00:46 +0000)
- Embed a reference to MemRegionManager objects in MemSpaceRegion objects
- Use this embedded reference for MemRegion objects to access ASTContext objects without external help
- Use this access to ASTContext to simplify 'isBoundable' (no ASTContext& argument required)

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

include/clang/Analysis/PathSensitive/GRState.h
include/clang/Analysis/PathSensitive/MemRegion.h
include/clang/Analysis/PathSensitive/ValueManager.h
lib/Analysis/BasicStore.cpp
lib/Analysis/CFRefCount.cpp
lib/Analysis/GRExprEngineInternalChecks.cpp
lib/Analysis/GRSimpleVals.cpp
lib/Analysis/MemRegion.cpp

index 6f95c6ff4ab01f192e43e674a2c81aeaf00c6923..a4077207780b68aefa8ade76f8266f0bacee6759 100644 (file)
@@ -613,7 +613,7 @@ public:
     // We only want to do fetches from regions that we can actually bind
     // values.  For example, SymbolicRegions of type 'id<...>' cannot
     // have direct bindings (but their can be bindings on their subregions).
-    if (!R->isBoundable(getContext()))
+    if (!R->isBoundable())
       return UnknownVal();
     
     if (const TypedRegion *TR = dyn_cast<TypedRegion>(R)) {
index 47d51119f82bee5248c69aba14e36005ac644b10..605fa27cc15550d94db646cd986ba04349198a24 100644 (file)
@@ -59,11 +59,14 @@ private:
 protected:
   MemRegion(Kind k) : kind(k) {}
   virtual ~MemRegion();
+  ASTContext &getContext() const;
 
 public:
   // virtual MemExtent getExtent(MemRegionManager& mrm) const = 0;
   virtual void Profile(llvm::FoldingSetNodeID& ID) const = 0;
-  
+
+  virtual MemRegionManager* getMemRegionManager() const = 0;
+
   std::string getString() const;
 
   virtual void print(llvm::raw_ostream& os) const;  
@@ -72,7 +75,7 @@ public:
   
   template<typename RegionTy> const RegionTy* getAs() const;
   
-  virtual bool isBoundable(ASTContext&) const { return true; }
+  virtual bool isBoundable() const { return true; }
 
   static bool classof(const MemRegion*) { return true; }
 };
@@ -81,14 +84,23 @@ public:
 ///  for example, the set of global variables, the stack frame, etc.
 class MemSpaceRegion : public MemRegion {
   friend class MemRegionManager;
-  MemSpaceRegion() : MemRegion(MemSpaceRegionKind) {}
+
+protected:
+  MemRegionManager *Mgr;
+
+  MemSpaceRegion(MemRegionManager *mgr) : MemRegion(MemSpaceRegionKind),
+                                          Mgr(mgr) {}
   
+  MemRegionManager* getMemRegionManager() const {
+    return Mgr;
+  }
+
 public:
   //RegionExtent getExtent() const { return UndefinedExtent(); }
 
   void Profile(llvm::FoldingSetNodeID& ID) const;
 
-  bool isBoundable(ASTContext &) const { return false; }
+  bool isBoundable() const { return false; }
 
   static bool classof(const MemRegion* R) {
     return R->getKind() == MemSpaceRegionKind;
@@ -101,11 +113,12 @@ class SubRegion : public MemRegion {
 protected:
   const MemRegion* superRegion;  
   SubRegion(const MemRegion* sReg, Kind k) : MemRegion(k), superRegion(sReg) {}
-  
 public:
   const MemRegion* getSuperRegion() const {
     return superRegion;
   }
+  
+  MemRegionManager* getMemRegionManager() const;
 
   bool isSubRegionOf(const MemRegion* R) const;
 
@@ -164,8 +177,8 @@ public:
     return getLocationType(C)->getDesugaredType();
   }
 
-  bool isBoundable(ASTContext &C) const {
-    return !getValueType(C).isNull();
+  bool isBoundable() const {
+    return !getValueType(getContext()).isNull();
   }
 
   static bool classof(const MemRegion* R) {
@@ -229,7 +242,7 @@ public:
     return const_cast<SymbolRef>(static_cast<const SymbolRef>(Data));
   }
   
-  bool isBoundable(ASTContext&) const { return false; }
+  bool isBoundable() const { return false; }
   
   virtual void print(llvm::raw_ostream& os) const;
 
@@ -329,7 +342,7 @@ public:
     return PTy->getPointeeType();
   }
   
-  bool isBoundable(ASTContext &C) const {
+  bool isBoundable() const {
     return isa<PointerType>(LValueType);
   }  
 
@@ -559,6 +572,7 @@ const RegionTy* MemRegion::getAs() const {
 //===----------------------------------------------------------------------===//
 
 class MemRegionManager {
+  ASTContext &C;
   llvm::BumpPtrAllocator& A;
   llvm::FoldingSet<MemRegion> Regions;
   
@@ -569,11 +583,13 @@ class MemRegionManager {
   MemSpaceRegion* code;
 
 public:
-  MemRegionManager(llvm::BumpPtrAllocator& a)
-    : A(a), globals(0), stack(0), heap(0), unknown(0), code(0) {}
+  MemRegionManager(ASTContext &c, llvm::BumpPtrAllocator& a)
+    : C(c), A(a), globals(0), stack(0), heap(0), unknown(0), code(0) {}
   
   ~MemRegionManager() {}
   
+  ASTContext &getContext() { return C; }
+  
   /// getStackRegion - Retrieve the memory region associated with the
   ///  current stack frame.
   MemSpaceRegion* getStackRegion();
@@ -666,9 +682,13 @@ private:
 };
   
 //===----------------------------------------------------------------------===//
-// Out-of-line member template definitions.
+// Out-of-line member definitions.
 //===----------------------------------------------------------------------===//
 
+inline ASTContext& MemRegion::getContext() const {
+  return getMemRegionManager()->getContext();
+}
+  
 template<typename RegionTy> struct MemRegionManagerTrait;
   
 template <typename RegionTy, typename A1>
index b86f4e875304fd4db322afc9d057ed9319a590e7..c28f0ea85511d1854c0629328a2ee4352027d6d5 100644 (file)
@@ -39,7 +39,7 @@ public:
   ValueManager(llvm::BumpPtrAllocator &alloc, ASTContext &context)
                : Context(context), BasicVals(Context, alloc),
                  SymMgr(Context, BasicVals, alloc),
-                 MemMgr(alloc) {}
+                 MemMgr(Context, alloc) {}
 
   // Accessors to submanagers.
   
index fcb405d2d20dc711fda67fc40544707d84979c92..dd23f31bbeb32eca7f9090d93f068b56ba14c754 100644 (file)
@@ -351,7 +351,7 @@ Store BasicStoreManager::BindInternal(Store store, Loc loc, SVal V) {
         // are incompatible.  This may also cause lots of breakage
         // elsewhere. Food for thought.
         if (const TypedRegion *TyR = dyn_cast<TypedRegion>(R)) {
-          if (TyR->isBoundable(C) &&
+          if (TyR->isBoundable() &&
               Loc::IsLocType(TyR->getValueType(C)))              
             V = X->getLoc();
         }
index c58ceb419324c953e035c54d7c194a923b7ec82f..204fbeeb4a8ab60ab9616cd6e16129bf6e3da65d 100644 (file)
@@ -2835,7 +2835,7 @@ void CFRefCount::EvalSummary(ExplodedNodeSet<GRState>& Dst,
           // Remove any existing reference-count binding.
           if (Sym) state = state->remove<RefBindings>(Sym);
           
-          if (R->isBoundable(Ctx)) {
+          if (R->isBoundable()) {
             // Set the value of the variable to be a conjured symbol.
             unsigned Count = Builder.getCurrentBlockCount();
             QualType T = R->getValueType(Ctx);
index 7f7270d40d640c4a01687ea090019c1fa7c34ec7..13df89ebbfdc4052cab69481b894f3cfbb5d6c7d 100644 (file)
@@ -717,7 +717,7 @@ public:
         if (isa<loc::ConcreteInt>(V)) {
           bool b = false;
           ASTContext &C = BRC.getASTContext();
-          if (R->isBoundable(C)) {
+          if (R->isBoundable()) {
             if (const TypedRegion *TR = dyn_cast<TypedRegion>(R)) {
               if (C.isObjCObjectPointerType(TR->getValueType(C))) {
                 os << "initialized to nil";
@@ -748,7 +748,7 @@ public:
       if (isa<loc::ConcreteInt>(V)) {
         bool b = false;
         ASTContext &C = BRC.getASTContext();
-        if (R->isBoundable(C)) {
+        if (R->isBoundable()) {
           if (const TypedRegion *TR = dyn_cast<TypedRegion>(R)) {
             if (C.isObjCObjectPointerType(TR->getValueType(C))) {
               os << "nil object reference stored to ";
index 7e54f1ad6866b479395b97bbdd8fe2431ad7db4f..878f46d9d51ac141f236d3a63d9998c7ee4b20d9 100644 (file)
@@ -367,8 +367,8 @@ void GRSimpleVals::EvalCall(ExplodedNodeSet<GRState>& Dst,
     
     if (isa<loc::MemRegionVal>(V)) {
       const MemRegion *R = cast<loc::MemRegionVal>(V).getRegion();
-      if (R->isBoundable(Eng.getContext()))
-       St = StateMgr.BindLoc(St, cast<Loc>(V), UnknownVal());
+      if (R->isBoundable())
+        St = StateMgr.BindLoc(St, cast<Loc>(V), UnknownVal());
     } else if (isa<nonloc::LocAsInteger>(V))
       St = StateMgr.BindLoc(St, cast<nonloc::LocAsInteger>(V).getLoc(),
                             UnknownVal());
index ad40f667d33f415025c3680b95dd4e4467b8018f..a923ac29eb338297cb413bb5431aac5190d07c60 100644 (file)
@@ -37,6 +37,19 @@ bool SubRegion::isSubRegionOf(const MemRegion* R) const {
   return false;
 }
 
+
+MemRegionManager* SubRegion::getMemRegionManager() const {
+  const SubRegion* r = this;
+  do {
+    const MemRegion *superRegion = r->getSuperRegion();
+    if (const SubRegion *sr = dyn_cast<SubRegion>(superRegion)) {
+      r = sr;
+      continue;
+    }
+    return superRegion->getMemRegionManager();
+  } while (1);
+}
+
 void MemSpaceRegion::Profile(llvm::FoldingSetNodeID& ID) const {
   ID.AddInteger((unsigned)getKind());
 }
@@ -192,13 +205,12 @@ void VarRegion::print(llvm::raw_ostream& os) const {
 // MemRegionManager methods.
 //===----------------------------------------------------------------------===//
   
-MemSpaceRegion* MemRegionManager::LazyAllocate(MemSpaceRegion*& region) {
-  
+MemSpaceRegion* MemRegionManager::LazyAllocate(MemSpaceRegion*& region) {  
   if (!region) {  
     region = (MemSpaceRegion*) A.Allocate<MemSpaceRegion>();
-    new (region) MemSpaceRegion();
+    new (region) MemSpaceRegion(this);
   }
-  
+
   return region;
 }