From: Ted Kremenek Date: Mon, 22 Jun 2009 23:13:13 +0000 (+0000) Subject: Refactor some of the logic in MemRegionManager for constructing regions using X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=250101353b711a409b075f1bc11070dddec7100b;p=clang Refactor some of the logic in MemRegionManager for constructing regions using member template functions and traits. The idea is to allow MemRegionManager to construct subclasses of MemRegion that aren't declared in MemRegion.h (e.g., checker-specific regions). git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@73917 91177308-0d34-0410-b5e6-96231b3b80d8 --- 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 + RegionTy* getRegion(const A1 a1); private: MemSpaceRegion* LazyAllocate(MemSpaceRegion*& region); }; + +//===----------------------------------------------------------------------===// +// Out-of-line member template definitions. +//===----------------------------------------------------------------------===// + +template struct MemRegionManagerTrait; + +template +RegionTy* MemRegionManager::getRegion(const A1 a1) { + + const typename MemRegionManagerTrait::SuperRegionTy *superRegion = + MemRegionManagerTrait::getSuperRegion(*this, a1); + + llvm::FoldingSetNodeID ID; + RegionTy::ProfileRegion(ID, a1, superRegion); + void* InsertPos; + RegionTy* R = cast_or_null(Regions.FindNodeOrInsertPos(ID, + InsertPos)); + + if (!R) { + R = (RegionTy*) A.Allocate(); + new (R) RegionTy(a1, superRegion); + Regions.InsertNode(R, InsertPos); + } + + return R; +} + +//===----------------------------------------------------------------------===// +// Traits for constructing regions. +//===----------------------------------------------------------------------===// + +template <> struct MemRegionManagerTrait { + typedef MemRegion SuperRegionTy; + static const SuperRegionTy* getSuperRegion(MemRegionManager& MRMgr, + const CompoundLiteralExpr *CL) { + + return CL->isFileScope() ? MRMgr.getGlobalsRegion() + : MRMgr.getStackRegion(); + } +}; + +template <> struct MemRegionManagerTrait { + typedef MemSpaceRegion SuperRegionTy; + static const SuperRegionTy* getSuperRegion(MemRegionManager& MRMgr, + const StringLiteral*) { + return MRMgr.getGlobalsRegion(); + } +}; + +template <> struct MemRegionManagerTrait { + typedef MemRegion SuperRegionTy; + static const SuperRegionTy* getSuperRegion(MemRegionManager& MRMgr, + const VarDecl *d) { + return d->hasLocalStorage() ? MRMgr.getStackRegion() + : MRMgr.getGlobalsRegion(); + } +}; + +template <> struct MemRegionManagerTrait { + 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(data); - - if (!R) { - R = (StringRegion*) A.Allocate(); - new (R) StringRegion(Str, GlobalsR); - Regions.InsertNode(R, InsertPos); - } +//===----------------------------------------------------------------------===// +// Constructing regions. +//===----------------------------------------------------------------------===// - return R; +StringRegion* MemRegionManager::getStringRegion(const StringLiteral* Str) { + return getRegion(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(data); - - if (!R) { - R = (VarRegion*) A.Allocate(); - new (R) VarRegion(d, superRegion); - Regions.InsertNode(R, InsertPos); - } - - return R; + return getRegion(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(data); - - if (!R) { - R = (CompoundLiteralRegion*) A.Allocate(); - new (R) CompoundLiteralRegion(CL, superRegion); - Regions.InsertNode(R, InsertPos); - } - - return R; + return getRegion(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(data); - - if (!R) { - R = (SymbolicRegion*) A.Allocate(); - // SymbolicRegion's storage class is usually unknown. - new (R) SymbolicRegion(sym, getUnknownRegion()); - Regions.InsertNode(R, InsertPos); - } - - return R; + return getRegion(sym); } FieldRegion* MemRegionManager::getFieldRegion(const FieldDecl* d,