aboutsummaryrefslogtreecommitdiff
path: root/lib/Analysis/RegionStore.cpp
diff options
context:
space:
mode:
authorZhongxing Xu <xuzhongxing@gmail.com>2009-06-25 05:29:39 +0000
committerZhongxing Xu <xuzhongxing@gmail.com>2009-06-25 05:29:39 +0000
commitc00346fff95b961241abffdcc257a90e6cb1cb4b (patch)
tree636af6523ca8375918f1e41068f513c0ca1894c6 /lib/Analysis/RegionStore.cpp
parent91a425cfd9dab4c4c6be69540db3617c03dff3ab (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.cpp89
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());