diff options
author | Zhongxing Xu <xuzhongxing@gmail.com> | 2009-06-25 04:50:44 +0000 |
---|---|---|
committer | Zhongxing Xu <xuzhongxing@gmail.com> | 2009-06-25 04:50:44 +0000 |
commit | 490b0f0877b1a6d3caf18abb4ab62ed592e13c4a (patch) | |
tree | 70ccf1ae5062186a489581c84b910453ab1430f0 | |
parent | 53ba0b636194dbeaa65a6f85316c9397a0c5298b (diff) |
Move all logic for retrieving ElementRegion binding into a separate method.
Revert to setting default value approach for handling struct initialization.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@74160 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Analysis/RegionStore.cpp | 64 |
1 files changed, 54 insertions, 10 deletions
diff --git a/lib/Analysis/RegionStore.cpp b/lib/Analysis/RegionStore.cpp index 65afe46bc0..9f55a63f38 100644 --- a/lib/Analysis/RegionStore.cpp +++ b/lib/Analysis/RegionStore.cpp @@ -302,7 +302,9 @@ public: /// else /// return symbolic SVal Retrieve(const GRState *state, Loc L, QualType T = QualType()); - + + SVal RetrieveField(const GRState* state, const FieldRegion* R); + /// Retrieve the values in a struct and return a CompoundVal, used when doing /// struct copy: /// struct s x, y; @@ -836,6 +838,9 @@ SVal RegionStoreManager::Retrieve(const GRState *state, Loc L, QualType T) { const TypedRegion *R = cast<TypedRegion>(MR); assert(R && "bad region"); + if (const FieldRegion* FR = dyn_cast<FieldRegion>(R)) + return RetrieveField(state, FR); + // FIXME: We should eventually handle funny addressing. e.g.: // // int x = ...; @@ -957,6 +962,52 @@ SVal RegionStoreManager::Retrieve(const GRState *state, Loc L, QualType T) { return UnknownVal(); } +SVal RegionStoreManager::RetrieveField(const GRState* state, + const FieldRegion* R) { + QualType Ty = R->getValueType(getContext()); + + // Check if the region has a binding. + RegionBindingsTy B = GetRegionBindings(state->getStore()); + const SVal* V = B.lookup(R); + if (V) + return *V; + + // Check if the region is killed. + if (state->contains<RegionKills>(R)) + return UnknownVal(); + + const MemRegion* SuperR = R->getSuperRegion(); + const SVal* D = state->get<RegionDefaultValue>(SuperR); + if (D) { + if (D->hasConjuredSymbol()) + return ValMgr.getRegionValueSymbolVal(R); + + if (D->isZeroConstant()) + return ValMgr.makeZeroVal(Ty); + + if (D->isUnknown()) + return *D; + + assert(0 && "Unknown default value"); + } + + if (R->hasHeapOrStackStorage()) + return UndefinedVal(); + + // If the region is already cast to another type, use that type to create the + // symbol value. + if (const QualType *p = state->get<RegionCasts>(R)) { + QualType tmp = *p; + Ty = tmp->getAsPointerType()->getPointeeType(); + } + + // All other integer values are symbolic. + if (Loc::IsLocType(Ty) || Ty->isIntegerType()) + return ValMgr.getRegionValueSymbolVal(R, Ty); + else + return UnknownVal(); +} + SVal RegionStoreManager::RetrieveStruct(const GRState *state, const TypedRegion* R){ QualType T = R->getValueType(getContext()); @@ -1179,15 +1230,8 @@ RegionStoreManager::BindStruct(const GRState *state, const TypedRegion* R, } // There may be fewer values in the initialize list than the fields of struct. - while (FI != FE) { - QualType FTy = (*FI)->getType(); - if (FTy->isIntegerType()) { - FieldRegion* FR = MRMgr.getFieldRegion(*FI, R); - state = Bind(state, ValMgr.makeLoc(FR), ValMgr.makeZeroVal(FTy)); - } - - ++FI; - } + if (FI != FE) + state = setDefaultValue(state, R, ValMgr.makeIntVal(0, false)); return state; } |