diff options
Diffstat (limited to 'clang/lib/Analysis/RegionStore.cpp')
| -rw-r--r-- | clang/lib/Analysis/RegionStore.cpp | 68 |
1 files changed, 67 insertions, 1 deletions
diff --git a/clang/lib/Analysis/RegionStore.cpp b/clang/lib/Analysis/RegionStore.cpp index f1c57b33bdf..732785c0f72 100644 --- a/clang/lib/Analysis/RegionStore.cpp +++ b/clang/lib/Analysis/RegionStore.cpp @@ -16,26 +16,46 @@ //===----------------------------------------------------------------------===// #include "clang/Analysis/PathSensitive/MemRegion.h" #include "clang/Analysis/PathSensitive/GRState.h" +#include "clang/Analysis/PathSensitive/GRStateTrait.h" #include "clang/Analysis/Analyses/LiveVariables.h" #include "llvm/ADT/ImmutableMap.h" +#include "llvm/ADT/ImmutableList.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Support/Compiler.h" using namespace clang; typedef llvm::ImmutableMap<const MemRegion*, SVal> RegionBindingsTy; +typedef llvm::ImmutableList<const MemRegion*> RegionViewTy; +typedef llvm::ImmutableMap<const MemRegion*, RegionViewTy> RegionViewMapTy; + +static int RegionViewMapTyIndex = 0; + +namespace clang { +template<> struct GRStateTrait<RegionViewMapTy> + : public GRStatePartialTrait<RegionViewMapTy> { + static void* GDMIndex() { return &RegionViewMapTyIndex; } +}; +} namespace { class VISIBILITY_HIDDEN RegionStoreManager : public StoreManager { RegionBindingsTy::Factory RBFactory; + RegionViewTy::Factory RVFactory; + RegionViewMapTy::Factory RVMFactory; + GRStateManager& StateMgr; MemRegionManager MRMgr; public: RegionStoreManager(GRStateManager& mgr) - : StateMgr(mgr), MRMgr(StateMgr.getAllocator()) {} + : RBFactory(mgr.getAllocator()), + RVFactory(mgr.getAllocator()), + RVMFactory(mgr.getAllocator()), + StateMgr(mgr), + MRMgr(StateMgr.getAllocator()) {} virtual ~RegionStoreManager() {} @@ -62,6 +82,9 @@ public: SVal ArrayToPointer(SVal Array); + const GRState* CastRegion(const GRState* St, SVal VoidPtr, + QualType CastToTy, Stmt* CastE); + SVal Retrieve(Store S, Loc L, QualType T = QualType()); Store Bind(Store St, Loc LV, SVal V); @@ -112,6 +135,9 @@ private: // Utility methods. BasicValueFactory& getBasicVals() { return StateMgr.getBasicVals(); } ASTContext& getContext() { return StateMgr.getContext(); } + + const GRState* AddRegionView(const GRState* St, + const MemRegion* View, const MemRegion* Base); }; } // end anonymous namespace @@ -238,6 +264,30 @@ SVal RegionStoreManager::ArrayToPointer(SVal Array) { return loc::MemRegionVal(ER); } +const GRState* RegionStoreManager::CastRegion(const GRState* St, + SVal VoidPtr, + QualType CastToTy, + Stmt* CastE) { + if (const AllocaRegion* AR = + dyn_cast<AllocaRegion>(cast<loc::MemRegionVal>(VoidPtr).getRegion())) { + + // Create a new region to attach type information to it. + const AnonTypedRegion* TR = MRMgr.getAnonTypedRegion(CastToTy, AR); + + // Get the pointer to the first element. + nonloc::ConcreteInt Idx(getBasicVals().getZeroWithPtrWidth(false)); + const ElementRegion* ER = MRMgr.getElementRegion(Idx, TR); + + St = StateMgr.BindExpr(St, CastE, loc::MemRegionVal(ER)); + + // Add a RegionView to base region. + return AddRegionView(St, TR, AR); + } + + // Default case. + return St; +} + SVal RegionStoreManager::Retrieve(Store S, Loc L, QualType T) { assert(!isa<UnknownVal>(L) && "location unknown"); assert(!isa<UndefinedVal>(L) && "location undefined"); @@ -600,3 +650,19 @@ Store RegionStoreManager::BindStructToVal(Store store, const TypedRegion* BaseR, return store; } + +const GRState* RegionStoreManager::AddRegionView(const GRState* St, + const MemRegion* View, + const MemRegion* Base) { + GRStateRef state(St, StateMgr); + + // First, retrieve the region view of the base region. + RegionViewMapTy::data_type* d = state.get<RegionViewMapTy>(Base); + RegionViewTy L = d ? *d : RVFactory.GetEmptyList(); + + // Now add View to the region view. + L = RVFactory.Add(View, L); + + // Create a new state with the new region view. + return state.set<RegionViewMapTy>(Base, L); +} |

