diff options
Diffstat (limited to 'clang')
-rw-r--r-- | clang/include/clang/Analysis/PathSensitive/MemRegion.h | 15 | ||||
-rw-r--r-- | clang/lib/Analysis/MemRegion.cpp | 62 |
2 files changed, 74 insertions, 3 deletions
diff --git a/clang/include/clang/Analysis/PathSensitive/MemRegion.h b/clang/include/clang/Analysis/PathSensitive/MemRegion.h index 9a361501cea..ed964978a44 100644 --- a/clang/include/clang/Analysis/PathSensitive/MemRegion.h +++ b/clang/include/clang/Analysis/PathSensitive/MemRegion.h @@ -35,6 +35,7 @@ namespace clang { class MemRegionManager; class MemSpaceRegion; class LocationContext; +class VarRegion; //===----------------------------------------------------------------------===// // Base region classes. @@ -42,6 +43,7 @@ class LocationContext; /// MemRegion - The root abstract class for all memory regions. class MemRegion : public llvm::FoldingSetNode { + friend class MemRegionManager; public: enum Kind { MemSpaceRegionKind, SymbolicRegionKind, @@ -329,13 +331,18 @@ public: class BlockDataRegion : public SubRegion { const BlockTextRegion *BC; const LocationContext *LC; + void *ReferencedVars; public: BlockDataRegion(const BlockTextRegion *bc, const LocationContext *lc, const MemRegion *sreg) - : SubRegion(sreg, BlockDataRegionKind), BC(bc), LC(lc) {} + : SubRegion(sreg, BlockDataRegionKind), BC(bc), LC(lc), ReferencedVars(0) {} const BlockTextRegion *getCodeRegion() const { return BC; } + + typedef const MemRegion * const * referenced_vars_iterator; + referenced_vars_iterator referenced_vars_begin() const; + referenced_vars_iterator referenced_vars_end() const; virtual void dumpToStream(llvm::raw_ostream& os) const; @@ -348,6 +355,8 @@ public: static bool classof(const MemRegion* R) { return R->getKind() == BlockDataRegionKind; } +private: + void LazyInitializeReferencedVars(); }; /// SymbolicRegion - A special, "non-concrete" region. Unlike other region @@ -650,9 +659,11 @@ public: : C(c), A(a), globals(0), stack(0), stackArguments(0), heap(0), unknown(0), code(0) {} - ~MemRegionManager() {} + ~MemRegionManager(); ASTContext &getContext() { return C; } + + llvm::BumpPtrAllocator &getAllocator() { return A; } /// getStackRegion - Retrieve the memory region associated with the /// current stack frame. diff --git a/clang/lib/Analysis/MemRegion.cpp b/clang/lib/Analysis/MemRegion.cpp index 430ec238c8d..af8bd16ee68 100644 --- a/clang/lib/Analysis/MemRegion.cpp +++ b/clang/lib/Analysis/MemRegion.cpp @@ -17,15 +17,25 @@ #include "clang/Analysis/PathSensitive/MemRegion.h" #include "clang/Analysis/PathSensitive/ValueManager.h" #include "clang/Analysis/PathSensitive/AnalysisContext.h" +#include "clang/AST/StmtVisitor.h" using namespace clang; //===----------------------------------------------------------------------===// -// Basic methods. +// Object destruction. //===----------------------------------------------------------------------===// MemRegion::~MemRegion() {} +MemRegionManager::~MemRegionManager() { + // All regions and their data are BumpPtrAllocated. No need to call + // their destructors. +} + +//===----------------------------------------------------------------------===// +// Basic methods. +//===----------------------------------------------------------------------===// + bool SubRegion::isSubRegionOf(const MemRegion* R) const { const MemRegion* r = getSuperRegion(); while (r != 0) { @@ -525,3 +535,53 @@ RegionRawOffset ElementRegion::getAsRawOffset() const { return RegionRawOffset(superR, offset); } +//===----------------------------------------------------------------------===// +// BlockDataRegion +//===----------------------------------------------------------------------===// + +void BlockDataRegion::LazyInitializeReferencedVars() { + if (ReferencedVars) + return; + + AnalysisContext *AC = LC->getAnalysisContext(); + AnalysisContext::referenced_decls_iterator I, E; + llvm::tie(I, E) = AC->getReferencedBlockVars(BC->getDecl()); + + if (I == E) { + ReferencedVars = (void*) 0x1; + return; + } + + MemRegionManager &MemMgr = *getMemRegionManager(); + llvm::BumpPtrAllocator &A = MemMgr.getAllocator(); + BumpVectorContext BC(A); + + typedef BumpVector<const MemRegion*> VarVec; + VarVec *BV = (VarVec*) A.Allocate<VarVec>(); + new (BV) VarVec(BC, (E - I) / sizeof(*I)); + + for ( ; I != E; ++I) + BV->push_back(MemMgr.getVarRegion(*I, LC), BC); + + ReferencedVars = BV; +} + +BlockDataRegion::referenced_vars_iterator +BlockDataRegion::referenced_vars_begin() const { + const_cast<BlockDataRegion*>(this)->LazyInitializeReferencedVars(); + + BumpVector<const MemRegion*> *Vec = + static_cast<BumpVector<const MemRegion*>*>(ReferencedVars); + + return Vec == (void*) 0x1 ? NULL : Vec->begin(); +} + +BlockDataRegion::referenced_vars_iterator +BlockDataRegion::referenced_vars_end() const { + const_cast<BlockDataRegion*>(this)->LazyInitializeReferencedVars(); + + BumpVector<const MemRegion*> *Vec = + static_cast<BumpVector<const MemRegion*>*>(ReferencedVars); + + return Vec == (void*) 0x1 ? NULL : Vec->end(); +} |