diff options
-rw-r--r-- | include/clang/Analysis/PathSensitive/MemRegion.h | 87 | ||||
-rw-r--r-- | lib/Analysis/MemRegion.cpp | 85 |
2 files changed, 97 insertions, 75 deletions
diff --git a/include/clang/Analysis/PathSensitive/MemRegion.h b/include/clang/Analysis/PathSensitive/MemRegion.h index 8afcc4c241..76d6a7a322 100644 --- a/include/clang/Analysis/PathSensitive/MemRegion.h +++ b/include/clang/Analysis/PathSensitive/MemRegion.h @@ -262,7 +262,9 @@ public: void Profile(llvm::FoldingSetNodeID& ID) const; - static void ProfileRegion(llvm::FoldingSetNodeID& ID, SymbolRef sym); + static void ProfileRegion(llvm::FoldingSetNodeID& ID, + SymbolRef sym, + const MemRegion* superRegion); void print(llvm::raw_ostream& os) const; @@ -277,7 +279,7 @@ class StringRegion : public TypedRegion { const StringLiteral* Str; protected: - StringRegion(const StringLiteral* str, MemRegion* sreg) + StringRegion(const StringLiteral* str, const MemRegion* sreg) : TypedRegion(sreg, StringRegionKind), Str(str) {} static void ProfileRegion(llvm::FoldingSetNodeID& ID, @@ -399,7 +401,7 @@ class VarRegion : public DeclRegion { VarRegion(const VarDecl* vd, const MemRegion* sReg) : DeclRegion(vd, sReg, VarRegionKind) {} - static void ProfileRegion(llvm::FoldingSetNodeID& ID, VarDecl* VD, + static void ProfileRegion(llvm::FoldingSetNodeID& ID, const VarDecl* VD, const MemRegion* superRegion) { DeclRegion::ProfileRegion(ID, VD, superRegion, VarRegionKind); } @@ -600,6 +602,8 @@ public: /// onHeap - check if the region is allocated on the heap, usually by malloc. bool onHeap(const MemRegion* R); + bool hasStackStorage(const MemRegion* R); + /// getAllocaRegion - Retrieve a region associated with a call to alloca(). AllocaRegion* getAllocaRegion(const Expr* Ex, unsigned Cnt); @@ -646,14 +650,87 @@ public: CodeTextRegion* getCodeTextRegion(SymbolRef sym, QualType t); CodeTextRegion* getCodeTextRegion(const FunctionDecl* fd, QualType t); - - bool hasStackStorage(const MemRegion* R); + + template <typename RegionTy, typename A1> + RegionTy* getRegion(const A1 a1); private: MemSpaceRegion* LazyAllocate(MemSpaceRegion*& region); }; + +//===----------------------------------------------------------------------===// +// Out-of-line member template definitions. +//===----------------------------------------------------------------------===// + +template<typename RegionTy> struct MemRegionManagerTrait; + +template <typename RegionTy, typename A1> +RegionTy* MemRegionManager::getRegion(const A1 a1) { + + const typename MemRegionManagerTrait<RegionTy>::SuperRegionTy *superRegion = + MemRegionManagerTrait<RegionTy>::getSuperRegion(*this, a1); + + llvm::FoldingSetNodeID ID; + RegionTy::ProfileRegion(ID, a1, superRegion); + void* InsertPos; + RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID, + InsertPos)); + + if (!R) { + R = (RegionTy*) A.Allocate<RegionTy>(); + new (R) RegionTy(a1, superRegion); + Regions.InsertNode(R, InsertPos); + } + + return R; +} + +//===----------------------------------------------------------------------===// +// Traits for constructing regions. +//===----------------------------------------------------------------------===// + +template <> struct MemRegionManagerTrait<CompoundLiteralRegion> { + typedef MemRegion SuperRegionTy; + static const SuperRegionTy* getSuperRegion(MemRegionManager& MRMgr, + const CompoundLiteralExpr *CL) { + + return CL->isFileScope() ? MRMgr.getGlobalsRegion() + : MRMgr.getStackRegion(); + } +}; + +template <> struct MemRegionManagerTrait<StringRegion> { + typedef MemSpaceRegion SuperRegionTy; + static const SuperRegionTy* getSuperRegion(MemRegionManager& MRMgr, + const StringLiteral*) { + return MRMgr.getGlobalsRegion(); + } +}; + +template <> struct MemRegionManagerTrait<VarRegion> { + typedef MemRegion SuperRegionTy; + static const SuperRegionTy* getSuperRegion(MemRegionManager& MRMgr, + const VarDecl *d) { + return d->hasLocalStorage() ? MRMgr.getStackRegion() + : MRMgr.getGlobalsRegion(); + } +}; + +template <> struct MemRegionManagerTrait<SymbolicRegion> { + typedef MemRegion SuperRegionTy; + static const SuperRegionTy* getSuperRegion(MemRegionManager& MRMgr, + SymbolRef) { + return MRMgr.getUnknownRegion(); + } +}; + + } // end clang namespace +//===----------------------------------------------------------------------===// +// Pretty-printing regions. +//===----------------------------------------------------------------------===// + namespace llvm { static inline raw_ostream& operator<<(raw_ostream& O, const clang::MemRegion* R) { diff --git a/lib/Analysis/MemRegion.cpp b/lib/Analysis/MemRegion.cpp index 9e11a26353..68804b141b 100644 --- a/lib/Analysis/MemRegion.cpp +++ b/lib/Analysis/MemRegion.cpp @@ -18,6 +18,9 @@ using namespace clang; +//===----------------------------------------------------------------------===// +// Basic methods. +//===----------------------------------------------------------------------===// MemRegion::~MemRegion() {} @@ -87,13 +90,15 @@ void DeclRegion::Profile(llvm::FoldingSetNodeID& ID) const { DeclRegion::ProfileRegion(ID, D, superRegion, getKind()); } -void SymbolicRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, SymbolRef sym) { +void SymbolicRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, SymbolRef sym, + const MemRegion *sreg) { ID.AddInteger((unsigned) MemRegion::SymbolicRegionKind); ID.Add(sym); + ID.AddPointer(sreg); } void SymbolicRegion::Profile(llvm::FoldingSetNodeID& ID) const { - SymbolicRegion::ProfileRegion(ID, sym); + SymbolicRegion::ProfileRegion(ID, sym, getSuperRegion()); } void ElementRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, @@ -230,68 +235,21 @@ bool MemRegionManager::onHeap(const MemRegion* R) { return (R != 0) && (R == heap); } -StringRegion* MemRegionManager::getStringRegion(const StringLiteral* Str) { - llvm::FoldingSetNodeID ID; - MemSpaceRegion* GlobalsR = getGlobalsRegion(); - - StringRegion::ProfileRegion(ID, Str, GlobalsR); - - void* InsertPos; - MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos); - StringRegion* R = cast_or_null<StringRegion>(data); - - if (!R) { - R = (StringRegion*) A.Allocate<StringRegion>(); - new (R) StringRegion(Str, GlobalsR); - Regions.InsertNode(R, InsertPos); - } +//===----------------------------------------------------------------------===// +// Constructing regions. +//===----------------------------------------------------------------------===// - return R; +StringRegion* MemRegionManager::getStringRegion(const StringLiteral* Str) { + return getRegion<StringRegion>(Str); } VarRegion* MemRegionManager::getVarRegion(const VarDecl* d) { - - const MemRegion* superRegion = d->hasLocalStorage() ? getStackRegion() - : getGlobalsRegion(); - - llvm::FoldingSetNodeID ID; - DeclRegion::ProfileRegion(ID, d, superRegion, MemRegion::VarRegionKind); - - void* InsertPos; - MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos); - VarRegion* R = cast_or_null<VarRegion>(data); - - if (!R) { - R = (VarRegion*) A.Allocate<VarRegion>(); - new (R) VarRegion(d, superRegion); - Regions.InsertNode(R, InsertPos); - } - - return R; + return getRegion<VarRegion>(d); } CompoundLiteralRegion* MemRegionManager::getCompoundLiteralRegion(const CompoundLiteralExpr* CL) { - // Is this compound literal allocated on the stack or is part of the - // global constant pool? - const MemRegion* superRegion = CL->isFileScope() ? - getGlobalsRegion() : getStackRegion(); - - // Profile the compound literal. - llvm::FoldingSetNodeID ID; - CompoundLiteralRegion::ProfileRegion(ID, CL, superRegion); - - void* InsertPos; - MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos); - CompoundLiteralRegion* R = cast_or_null<CompoundLiteralRegion>(data); - - if (!R) { - R = (CompoundLiteralRegion*) A.Allocate<CompoundLiteralRegion>(); - new (R) CompoundLiteralRegion(CL, superRegion); - Regions.InsertNode(R, InsertPos); - } - - return R; + return getRegion<CompoundLiteralRegion>(CL); } ElementRegion* @@ -351,20 +309,7 @@ CodeTextRegion* MemRegionManager::getCodeTextRegion(SymbolRef sym, QualType t) { /// getSymbolicRegion - Retrieve or create a "symbolic" memory region. SymbolicRegion* MemRegionManager::getSymbolicRegion(SymbolRef sym) { - llvm::FoldingSetNodeID ID; - SymbolicRegion::ProfileRegion(ID, sym); - void* InsertPos; - MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos); - SymbolicRegion* R = cast_or_null<SymbolicRegion>(data); - - if (!R) { - R = (SymbolicRegion*) A.Allocate<SymbolicRegion>(); - // SymbolicRegion's storage class is usually unknown. - new (R) SymbolicRegion(sym, getUnknownRegion()); - Regions.InsertNode(R, InsertPos); - } - - return R; + return getRegion<SymbolicRegion>(sym); } FieldRegion* MemRegionManager::getFieldRegion(const FieldDecl* d, |