aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZhongxing Xu <xuzhongxing@gmail.com>2009-06-25 04:50:44 +0000
committerZhongxing Xu <xuzhongxing@gmail.com>2009-06-25 04:50:44 +0000
commit490b0f0877b1a6d3caf18abb4ab62ed592e13c4a (patch)
tree70ccf1ae5062186a489581c84b910453ab1430f0
parent53ba0b636194dbeaa65a6f85316c9397a0c5298b (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.cpp64
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;
}