]> granicus.if.org Git - clang/commitdiff
Split CodeTextRegion into FunctionTextRegion and BlockTextRegion. This a precursor...
authorTed Kremenek <kremenek@apple.com>
Wed, 25 Nov 2009 01:32:22 +0000 (01:32 +0000)
committerTed Kremenek <kremenek@apple.com>
Wed, 25 Nov 2009 01:32:22 +0000 (01:32 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@89828 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Analysis/PathSensitive/MemRegion.h
include/clang/Analysis/PathSensitive/ValueManager.h
lib/Analysis/MemRegion.cpp
lib/Analysis/PthreadLockChecker.cpp
lib/Analysis/RegionStore.cpp
lib/Analysis/SVals.cpp
lib/Analysis/Store.cpp
lib/Analysis/ValueManager.cpp

index 06d0d976df011555b3bb103c36163b0fe98a367d..df9caedefc0d851a43eb2c981108691a1b4df0a3 100644 (file)
@@ -48,7 +48,8 @@ public:
               AllocaRegionKind,
               // Typed regions.
               BEG_TYPED_REGIONS,
-               CodeTextRegionKind,
+               FunctionTextRegionKind,
+               BlockTextRegionKind,
                CompoundLiteralRegionKind,
                StringRegionKind, ElementRegionKind,
                // Decl Regions.
@@ -237,43 +238,78 @@ public:
   }
 };
 
-/// CodeTextRegion - A region that represents code texts of a function. It wraps
-/// two kinds of code texts: real function and symbolic function. Real function
-/// is a function declared in the program. Symbolic function is a function
-/// pointer that we don't know which function it points to.
-class CodeTextRegion : public TypedRegion {
-  const FunctionDecl *FD;
 
+class CodeTextRegion : public TypedRegion {
+protected:
+  CodeTextRegion(const MemRegion *sreg, Kind k) : TypedRegion(sreg, k) {}
 public:
-
-  CodeTextRegion(const FunctionDecl* fd, const MemRegion* sreg)
-    : TypedRegion(sreg, CodeTextRegionKind), FD(fd) {}
-
   QualType getValueType(ASTContext &C) const {
     // Do not get the object type of a CodeTextRegion.
     assert(0);
     return QualType();
   }
+  
+  bool isBoundable() const { return false; }
+    
+  static bool classof(const MemRegion* R) {
+    Kind k = R->getKind();
+    return k >= FunctionTextRegionKind && k <= BlockTextRegionKind;
+  }
+};
 
+/// FunctionTextRegion - A region that represents code texts of function.
+class FunctionTextRegion : public CodeTextRegion {
+  const FunctionDecl *FD;
+public:
+  FunctionTextRegion(const FunctionDecl* fd, const MemRegion* sreg)
+    : CodeTextRegion(sreg, FunctionTextRegionKind), FD(fd) {}
+  
   QualType getLocationType(ASTContext &C) const {
     return C.getPointerType(FD->getType());
   }
-
+  
   const FunctionDecl *getDecl() const {
     return FD;
   }
-
-  bool isBoundable() const { return false; }
-
+    
   virtual void dumpToStream(llvm::raw_ostream& os) const;
-
+  
   void Profile(llvm::FoldingSetNodeID& ID) const;
-
+  
   static void ProfileRegion(llvm::FoldingSetNodeID& ID, const FunctionDecl *FD,
                             const MemRegion*);
-
+  
   static bool classof(const MemRegion* R) {
-    return R->getKind() == CodeTextRegionKind;
+    return R->getKind() == FunctionTextRegionKind;
+  }
+};
+  
+  
+/// BlockTextRegion - A region that represents code texts of blocks (closures).
+class BlockTextRegion : public CodeTextRegion {
+  const BlockDecl *BD;
+  CanQualType locTy;
+public:  
+  BlockTextRegion(const BlockDecl *bd, CanQualType lTy, const MemRegion* sreg)
+    : CodeTextRegion(sreg, BlockTextRegionKind), BD(bd), locTy(lTy) {}
+  
+  QualType getLocationType(ASTContext &C) const {
+    return locTy;
+  }
+  
+  const BlockDecl *getDecl() const {
+    return BD;
+  }
+    
+  virtual void dumpToStream(llvm::raw_ostream& os) const;
+  
+  void Profile(llvm::FoldingSetNodeID& ID) const;
+  
+  static void ProfileRegion(llvm::FoldingSetNodeID& ID, const BlockDecl *BD,
+                            CanQualType, const MemRegion*);
+  
+  static bool classof(const MemRegion* R) {
+    return R->getKind() == BlockTextRegionKind;
   }
 };
 
@@ -656,7 +692,9 @@ public:
   ObjCIvarRegion *getObjCIvarRegion(const ObjCIvarDecl* ivd,
                                     const MemRegion* superRegion);
 
-  CodeTextRegion *getCodeTextRegion(const FunctionDecl *FD);
+  FunctionTextRegion *getFunctionTextRegion(const FunctionDecl *FD);
+  BlockTextRegion *getBlockTextRegion(const BlockDecl *BD, CanQualType locTy);
+
 
   template <typename RegionTy, typename A1>
   RegionTy* getRegion(const A1 a1);
@@ -801,18 +839,21 @@ template <> struct MemRegionManagerTrait<SymbolicRegion> {
   }
 };
 
-template<> struct MemRegionManagerTrait<CodeTextRegion> {
+template<> struct MemRegionManagerTrait<FunctionTextRegion> {
   typedef MemSpaceRegion SuperRegionTy;
   static const SuperRegionTy* getSuperRegion(MemRegionManager& MRMgr,
                                              const FunctionDecl*) {
     return MRMgr.getCodeRegion();
   }
+};
+template<> struct MemRegionManagerTrait<BlockTextRegion> {
+  typedef MemSpaceRegion SuperRegionTy;
   static const SuperRegionTy* getSuperRegion(MemRegionManager& MRMgr,
-                                             SymbolRef, QualType) {
+                                             const BlockDecl*, CanQualType) {
     return MRMgr.getCodeRegion();
   }
 };
-
+  
 } // end clang namespace
 
 //===----------------------------------------------------------------------===//
index 8d162a681c446ddb684c914c3c5af36ba5bc673e..66d431586424a3e8ca6a5fc9c63d5d1d9297f5e2 100644 (file)
@@ -114,6 +114,8 @@ public:
                                                       const TypedRegion *R);
 
   DefinedSVal getFunctionPointer(const FunctionDecl *FD);
+  
+  DefinedSVal getBlockPointer(const BlockDecl *BD, CanQualType locTy);
 
   NonLoc makeCompoundVal(QualType T, llvm::ImmutableList<SVal> Vals) {
     return nonloc::CompoundVal(BasicVals.getCompoundValData(T, Vals));
index 8c0b85c0c729689c6cf848b1da10d5f6ede43608..8b4c7a6a24078f525743ab6c2f60b30761b70f51 100644 (file)
@@ -126,15 +126,26 @@ void ElementRegion::Profile(llvm::FoldingSetNodeID& ID) const {
   ElementRegion::ProfileRegion(ID, ElementType, Index, superRegion);
 }
 
-void CodeTextRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
-                                   const FunctionDecl *FD,
-                                   const MemRegion*) {
-  ID.AddInteger(MemRegion::CodeTextRegionKind);
+void FunctionTextRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
+                                       const FunctionDecl *FD,
+                                       const MemRegion*) {
+  ID.AddInteger(MemRegion::FunctionTextRegionKind);
   ID.AddPointer(FD);
 }
 
-void CodeTextRegion::Profile(llvm::FoldingSetNodeID& ID) const {
-  CodeTextRegion::ProfileRegion(ID, FD, superRegion);
+void FunctionTextRegion::Profile(llvm::FoldingSetNodeID& ID) const {
+  FunctionTextRegion::ProfileRegion(ID, FD, superRegion);
+}
+
+void BlockTextRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
+                                   const BlockDecl *BD, CanQualType,
+                                   const MemRegion*) {
+  ID.AddInteger(MemRegion::BlockTextRegionKind);
+  ID.AddPointer(BD);
+}
+
+void BlockTextRegion::Profile(llvm::FoldingSetNodeID& ID) const {
+  BlockTextRegion::ProfileRegion(ID, BD, locTy, superRegion);
 }
 
 //===----------------------------------------------------------------------===//
@@ -160,10 +171,14 @@ void AllocaRegion::dumpToStream(llvm::raw_ostream& os) const {
   os << "alloca{" << (void*) Ex << ',' << Cnt << '}';
 }
 
-void CodeTextRegion::dumpToStream(llvm::raw_ostream& os) const {
+void FunctionTextRegion::dumpToStream(llvm::raw_ostream& os) const {
   os << "code{" << getDecl()->getDeclName().getAsString() << '}';
 }
 
+void BlockTextRegion::dumpToStream(llvm::raw_ostream& os) const {
+  os << "block{" << (void*) this << '}';
+}
+
 void CompoundLiteralRegion::dumpToStream(llvm::raw_ostream& os) const {
   // FIXME: More elaborate pretty-printing.
   os << "{ " << (void*) CL <<  " }";
@@ -287,10 +302,17 @@ MemRegionManager::getElementRegion(QualType elementType, SVal Idx,
   return R;
 }
 
-CodeTextRegion *MemRegionManager::getCodeTextRegion(const FunctionDecl *FD) {
-  return getRegion<CodeTextRegion>(FD);
+FunctionTextRegion *
+MemRegionManager::getFunctionTextRegion(const FunctionDecl *FD) {
+  return getRegion<FunctionTextRegion>(FD);
 }
 
+BlockTextRegion *MemRegionManager::getBlockTextRegion(const BlockDecl *BD,
+                                                      CanQualType locTy) {
+  return getRegion<BlockTextRegion>(BD, locTy);
+}
+
+
 /// getSymbolicRegion - Retrieve or create a "symbolic" memory region.
 SymbolicRegion* MemRegionManager::getSymbolicRegion(SymbolRef sym) {
   return getRegion<SymbolicRegion>(sym);
index 66206616b0089789cec2ca7b2583cba2475663f3..dc6a63dd07934dff01c119b6df6791dccc3f095b 100644 (file)
@@ -59,8 +59,8 @@ void PthreadLockChecker::PostVisitCallExpr(CheckerContext &C,
                                            const CallExpr *CE) {
   const GRState *state = C.getState();
   const Expr *Callee = CE->getCallee();
-  const CodeTextRegion *R =
-    dyn_cast_or_null<CodeTextRegion>(state->getSVal(Callee).getAsRegion());
+  const FunctionTextRegion *R =
+    dyn_cast_or_null<FunctionTextRegion>(state->getSVal(Callee).getAsRegion());
   
   if (!R)
     return;
index af2e359a00e4d92b546dc6b279b68211067343aa..16a4690f95ad1ce44df11e471e60b18ea88caf3a 100644 (file)
@@ -712,7 +712,8 @@ DefinedOrUnknownSVal RegionStoreManager::getSizeInElements(const GRState *state,
       assert(0 && "Cannot index into a MemSpace");
       return UnknownVal();
 
-    case MemRegion::CodeTextRegionKind:
+    case MemRegion::FunctionTextRegionKind:
+    case MemRegion::BlockTextRegionKind:
       // Technically this can happen if people do funny things with casts.
       return UnknownVal();
 
@@ -857,7 +858,8 @@ SVal RegionStoreManager::EvalBinOp(const GRState *state,
     case MemRegion::ObjCIvarRegionKind:
       return UnknownVal();
 
-    case MemRegion::CodeTextRegionKind:
+    case MemRegion::FunctionTextRegionKind:
+    case MemRegion::BlockTextRegionKind:
       // Technically this can happen if people do funny things with casts.
       return UnknownVal();
 
index d5d36e3b90909b884a8647a897fa4d6de4eb6f89..9163b2725273ae2b6567b50f04606d1a8a5aae76 100644 (file)
@@ -51,7 +51,7 @@ bool SVal::hasConjuredSymbol() const {
 const FunctionDecl *SVal::getAsFunctionDecl() const {
   if (const loc::MemRegionVal* X = dyn_cast<loc::MemRegionVal>(this)) {
     const MemRegion* R = X->getRegion();
-    if (const CodeTextRegion *CTR = R->getAs<CodeTextRegion>())
+    if (const FunctionTextRegion *CTR = R->getAs<FunctionTextRegion>())
       return CTR->getDecl();
   }
 
index 4183a73158b5001831e6ac61347720df774ef82e..14f55fd75fafdebda6619d67bdc3bbc61e50fdfa 100644 (file)
@@ -85,7 +85,9 @@ const MemRegion *StoreManager::CastRegion(const MemRegion *R, QualType CastToTy)
       assert(0 && "Invalid region cast");
       break;
     }
-    case MemRegion::CodeTextRegionKind: {
+    
+    case MemRegion::FunctionTextRegionKind:
+    case MemRegion::BlockTextRegionKind: {
       // CodeTextRegion should be cast to only a function or block pointer type,
       // although they can in practice be casted to anything, e.g, void*, char*,
       // etc.  
index fe670e79b3b534da49831a57aab65c31ed69d0f3..37df44360226e192434eeb7f143073681bc6f192 100644 (file)
@@ -138,6 +138,13 @@ ValueManager::getDerivedRegionValueSymbolVal(SymbolRef parentSymbol,
 }
 
 DefinedSVal ValueManager::getFunctionPointer(const FunctionDecl* FD) {
-  CodeTextRegion *R  = MemMgr.getCodeTextRegion(FD);
+  CodeTextRegion *R  = MemMgr.getFunctionTextRegion(FD);
   return loc::MemRegionVal(R);
 }
+
+DefinedSVal ValueManager::getBlockPointer(const BlockDecl *BD,
+                                          CanQualType locTy) {
+  CodeTextRegion *R  = MemMgr.getBlockTextRegion(BD, locTy);
+  return loc::MemRegionVal(R);
+}
+