diff options
Diffstat (limited to 'lib/Checker/FlatStore.cpp')
-rw-r--r-- | lib/Checker/FlatStore.cpp | 48 |
1 files changed, 37 insertions, 11 deletions
diff --git a/lib/Checker/FlatStore.cpp b/lib/Checker/FlatStore.cpp index 64575b3c97..51c537ecfa 100644 --- a/lib/Checker/FlatStore.cpp +++ b/lib/Checker/FlatStore.cpp @@ -74,7 +74,14 @@ private: return RegionBindings(static_cast<const RegionBindings::TreeTy*>(store)); } - Interval RegionToInterval(const MemRegion *R); + class RegionInterval { + public: + const MemRegion *R; + Interval I; + RegionInterval(const MemRegion *r, uint64_t s, uint64_t e) : R(r), I(s, e){} + }; + + RegionInterval RegionToInterval(const MemRegion *R); SVal RetrieveRegionWithNoBinding(const MemRegion *R, QualType T); }; @@ -86,11 +93,14 @@ StoreManager *clang::CreateFlatStoreManager(GRStateManager &StMgr) { SVal FlatStoreManager::Retrieve(Store store, Loc L, QualType T) { const MemRegion *R = cast<loc::MemRegionVal>(L).getRegion(); - Interval I = RegionToInterval(R); + RegionInterval RI = RegionToInterval(R); + + assert(RI.R && "should handle regions with unknown interval"); + RegionBindings B = getRegionBindings(store); - const BindingVal *BV = B.lookup(R); + const BindingVal *BV = B.lookup(RI.R); if (BV) { - const SVal *V = BVFactory.Lookup(*BV, I); + const SVal *V = BVFactory.Lookup(*BV, RI.I); if (V) return *V; else @@ -116,9 +126,10 @@ Store FlatStoreManager::Bind(Store store, Loc L, SVal val) { if (V) BV = *V; - Interval I = RegionToInterval(R); - BV = BVFactory.Add(BV, I, val); - B = RBFactory.Add(B, R, BV); + RegionInterval RI = RegionToInterval(R); + assert(RI.R && "should handle regions with unknown interval"); + BV = BVFactory.Add(BV, RI.I, val); + B = RBFactory.Add(B, RI.R, BV); return B.getRoot(); } @@ -139,7 +150,7 @@ SVal FlatStoreManager::ArrayToPointer(Loc Array) { Store FlatStoreManager::BindDecl(Store store, const VarRegion *VR, SVal initVal) { - return store; + return Bind(store, ValMgr.makeLoc(VR), initVal); } Store FlatStoreManager::BindDeclWithNoInit(Store store, const VarRegion *VR) { @@ -170,15 +181,30 @@ void FlatStoreManager::print(Store store, llvm::raw_ostream& Out, void FlatStoreManager::iterBindings(Store store, BindingsHandler& f) { } -Interval FlatStoreManager::RegionToInterval(const MemRegion *R) { +FlatStoreManager::RegionInterval +FlatStoreManager::RegionToInterval(const MemRegion *R) { switch (R->getKind()) { case MemRegion::VarRegionKind: { QualType T = cast<VarRegion>(R)->getValueType(Ctx); uint64_t Size = Ctx.getTypeSize(T); - return Interval(0, Size-1); + return RegionInterval(R, 0, Size-1); } + + case MemRegion::ElementRegionKind: + case MemRegion::FieldRegionKind: { + const TypedRegion *TR = cast<TypedRegion>(R); + RegionOffset Offset = TR->getAsOffset(); + // We cannot compute offset for all ElementRegions, for example, elements + // with symbolic offsets. + if (!Offset.getRegion()) + return RegionInterval(0, 0, 0); + uint64_t Start = Offset.getOffset(); + uint64_t Size = Ctx.getTypeSize(TR->getValueType(Ctx)); + return RegionInterval(Offset.getRegion(), Start, Start+Size); + } + default: llvm_unreachable("Region kind unhandled."); - return Interval(0, 0); + return RegionInterval(0, 0, 0); } } |