From: Zhongxing Xu Date: Fri, 31 Oct 2008 07:16:08 +0000 (+0000) Subject: Implement load from struct region. Instead of returning an UnknownVal(), we create... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=6e3f01cef27dd6cc7e36769618820c5b984f61da;p=clang Implement load from struct region. Instead of returning an UnknownVal(), we create a CompoundVal by loading from each field of the struct. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@58494 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Analysis/RegionStore.cpp b/lib/Analysis/RegionStore.cpp index d5fb4d2a9a..c2a5da7289 100644 --- a/lib/Analysis/RegionStore.cpp +++ b/lib/Analysis/RegionStore.cpp @@ -113,6 +113,12 @@ private: Store InitializeArrayToUndefined(Store store, QualType T, MemRegion* BaseR); Store InitializeStructToUndefined(Store store, QualType T, MemRegion* BaseR); + + SVal RetrieveStruct(Store store, const TypedRegion* R); + + // Utility methods. + BasicValueFactory& getBasicVals() { return StateMgr.getBasicVals(); } + ASTContext& getContext() { return StateMgr.getContext(); } }; } // end anonymous namespace @@ -224,6 +230,10 @@ SVal RegionStoreManager::Retrieve(Store S, Loc L, QualType T) { const MemRegion* R = cast(L).getRegion(); assert(R && "bad region"); + if (const TypedRegion* TR = dyn_cast(R)) + if (TR->getType(getContext())->isStructureType()) + return RetrieveStruct(S, TR); + RegionBindingsTy B(static_cast(S)); RegionBindingsTy::data_type* V = B.lookup(R); return V ? *V : UnknownVal(); @@ -244,6 +254,29 @@ SVal RegionStoreManager::Retrieve(Store S, Loc L, QualType T) { } } +SVal RegionStoreManager::RetrieveStruct(Store store, const TypedRegion* R) { + QualType T = R->getType(getContext()); + assert(T->isStructureType()); + + const RecordType* RT = cast(T.getTypePtr()); + RecordDecl* RD = RT->getDecl(); + assert(RD->isDefinition()); + + llvm::ImmutableList StructVal = getBasicVals().getEmptySValList(); + + for (int i = RD->getNumMembers() - 1; i >= 0; --i) { + FieldRegion* FR = MRMgr.getFieldRegion(RD->getMember(i), R); + RegionBindingsTy B(static_cast(store)); + RegionBindingsTy::data_type* data = B.lookup(R); + + SVal FieldValue = data ? *data : UnknownVal(); + + StructVal = getBasicVals().consVals(FieldValue, StructVal); + } + + return NonLoc::MakeCompoundVal(T, StructVal, getBasicVals()); +} + Store RegionStoreManager::Bind(Store store, Loc LV, SVal V) { if (LV.getSubKind() == loc::SymbolValKind) return store;