diff options
author | Zhongxing Xu <xuzhongxing@gmail.com> | 2009-06-25 05:29:39 +0000 |
---|---|---|
committer | Zhongxing Xu <xuzhongxing@gmail.com> | 2009-06-25 05:29:39 +0000 |
commit | c00346fff95b961241abffdcc257a90e6cb1cb4b (patch) | |
tree | 636af6523ca8375918f1e41068f513c0ca1894c6 /lib/Analysis/RegionStore.cpp | |
parent | 91a425cfd9dab4c4c6be69540db3617c03dff3ab (diff) |
Move element region retrieving logic into a separate function.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@74166 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis/RegionStore.cpp')
-rw-r--r-- | lib/Analysis/RegionStore.cpp | 89 |
1 files changed, 58 insertions, 31 deletions
diff --git a/lib/Analysis/RegionStore.cpp b/lib/Analysis/RegionStore.cpp index 9f55a63f38..2bb97e9f82 100644 --- a/lib/Analysis/RegionStore.cpp +++ b/lib/Analysis/RegionStore.cpp @@ -303,6 +303,8 @@ public: /// return symbolic SVal Retrieve(const GRState *state, Loc L, QualType T = QualType()); + SVal RetrieveElement(const GRState* state, const ElementRegion* R); + SVal RetrieveField(const GRState* state, const FieldRegion* R); /// Retrieve the values in a struct and return a CompoundVal, used when doing @@ -841,6 +843,9 @@ SVal RegionStoreManager::Retrieve(const GRState *state, Loc L, QualType T) { if (const FieldRegion* FR = dyn_cast<FieldRegion>(R)) return RetrieveField(state, FR); + if (const ElementRegion* ER = dyn_cast<ElementRegion>(R)) + return RetrieveElement(state, ER); + // FIXME: We should eventually handle funny addressing. e.g.: // // int x = ...; @@ -873,37 +878,6 @@ SVal RegionStoreManager::Retrieve(const GRState *state, Loc L, QualType T) { if (state->contains<RegionKills>(R)) return UnknownVal(); - // Check if the region is an element region of a string literal. - if (const ElementRegion *ER = dyn_cast<ElementRegion>(R)) { - if (const StringRegion *StrR=dyn_cast<StringRegion>(ER->getSuperRegion())) { - const StringLiteral *Str = StrR->getStringLiteral(); - SVal Idx = ER->getIndex(); - if (nonloc::ConcreteInt *CI = dyn_cast<nonloc::ConcreteInt>(&Idx)) { - int64_t i = CI->getValue().getSExtValue(); - char c; - if (i == Str->getByteLength()) - c = '\0'; - else - c = Str->getStrData()[i]; - const llvm::APSInt &V = getBasicVals().getValue(c, getContext().CharTy); - return nonloc::ConcreteInt(V); - } - } - } - - // If the region is an element or field, it may have a default value. - if (isa<ElementRegion>(R) || isa<FieldRegion>(R)) { - const MemRegion* SuperR = cast<SubRegion>(R)->getSuperRegion(); - const SVal* D = state->get<RegionDefaultValue>(SuperR); - if (D) { - // If the default value is symbolic, we need to create a new symbol. - if (D->hasConjuredSymbol()) - return ValMgr.getRegionValueSymbolVal(R); - else - return *D; - } - } - if (const ObjCIvarRegion *IVR = dyn_cast<ObjCIvarRegion>(R)) { const MemRegion *SR = IVR->getSuperRegion(); @@ -962,6 +936,59 @@ SVal RegionStoreManager::Retrieve(const GRState *state, Loc L, QualType T) { return UnknownVal(); } +SVal RegionStoreManager::RetrieveElement(const GRState* state, + const ElementRegion* R) { + // 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(); + + // Check if the region is an element region of a string literal. + if (const StringRegion *StrR=dyn_cast<StringRegion>(R->getSuperRegion())) { + const StringLiteral *Str = StrR->getStringLiteral(); + SVal Idx = R->getIndex(); + if (nonloc::ConcreteInt *CI = dyn_cast<nonloc::ConcreteInt>(&Idx)) { + int64_t i = CI->getValue().getSExtValue(); + char c; + if (i == Str->getByteLength()) + c = '\0'; + else + c = Str->getStrData()[i]; + return ValMgr.makeIntVal(c, getContext().CharTy); + } + } + + const MemRegion* SuperR = R->getSuperRegion(); + const SVal* D = state->get<RegionDefaultValue>(SuperR); + + if (D) { + if (D->hasConjuredSymbol()) + return ValMgr.getRegionValueSymbolVal(R); + else + return *D; + } + + if (R->hasHeapOrStackStorage()) + return UndefinedVal(); + + QualType Ty = R->getValueType(getContext()); + + // 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)) + Ty = (*p)->getAsPointerType()->getPointeeType(); + + if (Loc::IsLocType(Ty) || Ty->isIntegerType()) + return ValMgr.getRegionValueSymbolVal(R, Ty); + else + return UnknownVal(); +} + SVal RegionStoreManager::RetrieveField(const GRState* state, const FieldRegion* R) { QualType Ty = R->getValueType(getContext()); |