aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2009-06-22 23:13:13 +0000
committerTed Kremenek <kremenek@apple.com>2009-06-22 23:13:13 +0000
commit250101353b711a409b075f1bc11070dddec7100b (patch)
treefc9e403457302253cc7e78a493d3b1441f927868
parentd7f37bf8b9a211455c5037df7b7e88e5a9510119 (diff)
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
-rw-r--r--include/clang/Analysis/PathSensitive/MemRegion.h87
-rw-r--r--lib/Analysis/MemRegion.cpp85
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,