diff options
author | Zhongxing Xu <xuzhongxing@gmail.com> | 2008-10-31 10:53:01 +0000 |
---|---|---|
committer | Zhongxing Xu <xuzhongxing@gmail.com> | 2008-10-31 10:53:01 +0000 |
commit | af0a844542247d337947b4585e684b5eb72d4ffb (patch) | |
tree | 1138b14c10a5032f1be1f2d4542fd4d261537e1e /lib/Analysis/RegionStore.cpp | |
parent | 1a12a0ea00a62d785ce8c25e740a152015a3000a (diff) |
Implement struct initialization for SCA.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@58506 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis/RegionStore.cpp')
-rw-r--r-- | lib/Analysis/RegionStore.cpp | 48 |
1 files changed, 47 insertions, 1 deletions
diff --git a/lib/Analysis/RegionStore.cpp b/lib/Analysis/RegionStore.cpp index 3eb3946961..9694854ee3 100644 --- a/lib/Analysis/RegionStore.cpp +++ b/lib/Analysis/RegionStore.cpp @@ -113,6 +113,7 @@ private: Store InitializeArray(Store store, TypedRegion* R, SVal Init); Store InitializeArrayToUndefined(Store store, QualType T, MemRegion* BaseR); + Store InitializeStruct(Store store, TypedRegion* R, SVal Init); Store InitializeStructToUndefined(Store store, QualType T, MemRegion* BaseR); SVal RetrieveStruct(Store store, const TypedRegion* R); @@ -409,7 +410,10 @@ Store RegionStoreManager::BindDecl(Store store, const VarDecl* VD, Expr* Ex, store = InitializeArray(store, VR, InitVal); } else if (T->isStructureType()) { - store = InitializeStructToUndefined(store, T, VR); + if (!Ex) + store = InitializeStructToUndefined(store, T, VR); + else + store = InitializeStruct(store, VR, InitVal); } // Other types of local variables are not handled yet. @@ -480,6 +484,48 @@ Store RegionStoreManager::InitializeArrayToUndefined(Store store, QualType T, return store; } +Store RegionStoreManager::InitializeStruct(Store store, TypedRegion* R, + SVal Init) { + QualType T = R->getType(getContext()); + assert(T->isStructureType()); + + RecordType* RT = cast<RecordType>(T.getTypePtr()); + RecordDecl* RD = RT->getDecl(); + assert(RD->isDefinition()); + + nonloc::CompoundVal& CV = cast<nonloc::CompoundVal>(Init); + nonloc::CompoundVal::iterator VI = CV.begin(), VE = CV.end(); + RecordDecl::field_iterator FI = RD->field_begin(), FE = RD->field_end(); + + for (; FI != FE; ++FI) { + QualType FTy = (*FI)->getType(); + FieldRegion* FR = MRMgr.getFieldRegion(*FI, R); + + if (Loc::IsLocType(FTy) || FTy->isIntegerType()) { + if (VI != VE) { + store = Bind(store, loc::MemRegionVal(FR), *VI); + ++VI; + } else + store = Bind(store, loc::MemRegionVal(FR), UndefinedVal()); + } + else if (FTy->isArrayType()) { + if (VI != VE) { + store = InitializeArray(store, FR, *VI); + ++VI; + } else + store = InitializeArrayToUndefined(store, FTy, FR); + } + else if (FTy->isStructureType()) { + if (VI != VE) { + store = InitializeStruct(store, FR, *VI); + ++VI; + } else + store = InitializeStructToUndefined(store, FTy, FR); + } + } + return store; +} + Store RegionStoreManager::InitializeStructToUndefined(Store store, QualType T, MemRegion* BaseR) { QualType CT = StateMgr.getContext().getCanonicalType(T); |