aboutsummaryrefslogtreecommitdiff
path: root/lib/Analysis/RegionStore.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Analysis/RegionStore.cpp')
-rw-r--r--lib/Analysis/RegionStore.cpp54
1 files changed, 54 insertions, 0 deletions
diff --git a/lib/Analysis/RegionStore.cpp b/lib/Analysis/RegionStore.cpp
index 1bd29add30..f64ed76be7 100644
--- a/lib/Analysis/RegionStore.cpp
+++ b/lib/Analysis/RegionStore.cpp
@@ -44,6 +44,10 @@ public:
SVal getLValueField(const GRState* St, SVal Base, const FieldDecl* D);
+ SVal getLValueElement(const GRState* St, SVal Base, SVal Offset);
+
+ SVal ArrayToPointer(SVal Array);
+
SVal Retrieve(Store S, Loc L, QualType T);
Store Bind(Store St, Loc LV, SVal V);
@@ -124,6 +128,56 @@ SVal RegionStoreManager::getLValueField(const GRState* St, SVal Base,
return loc::MemRegionVal(MRMgr.getFieldRegion(D, BaseR));
}
+SVal RegionStoreManager::getLValueElement(const GRState* St,
+ SVal Base, SVal Offset) {
+ if (Base.isUnknownOrUndef())
+ return Base;
+
+ loc::MemRegionVal& BaseL = cast<loc::MemRegionVal>(Base);
+
+ // We expect BaseR is an ElementRegion, not a base VarRegion.
+
+ const ElementRegion* ElemR = cast<ElementRegion>(BaseL.getRegion());
+
+ SVal Idx = ElemR->getIndex();
+
+ nonloc::ConcreteInt *CI1, *CI2;
+
+ // Only handle integer indices for now.
+ if ((CI1 = dyn_cast<nonloc::ConcreteInt>(&Idx)) &&
+ (CI2 = dyn_cast<nonloc::ConcreteInt>(&Offset))) {
+ SVal NewIdx = CI1->EvalBinOp(StateMgr.getBasicVals(), BinaryOperator::Add,
+ *CI2);
+ return loc::MemRegionVal(MRMgr.getElementRegion(NewIdx,
+ ElemR->getSuperRegion()));
+ }
+
+ return UnknownVal();
+}
+
+// Cast 'pointer to array' to 'pointer to the first element of array'.
+
+SVal RegionStoreManager::ArrayToPointer(SVal Array) {
+ const MemRegion* ArrayR = cast<loc::MemRegionVal>(&Array)->getRegion();
+
+ const VarDecl* D = cast<VarRegion>(ArrayR)->getDecl();
+
+ if (const ConstantArrayType* CAT =
+ dyn_cast<ConstantArrayType>(D->getType().getTypePtr())) {
+
+ BasicValueFactory& BasicVals = StateMgr.getBasicVals();
+
+ nonloc::ConcreteInt Idx(BasicVals.getValue(0, CAT->getSize().getBitWidth(),
+ false));
+
+ ElementRegion* ER = MRMgr.getElementRegion(Idx, ArrayR);
+
+ return loc::MemRegionVal(ER);
+ }
+
+ return Array;
+}
+
SVal RegionStoreManager::Retrieve(Store S, Loc L, QualType T) {
assert(!isa<UnknownVal>(L) && "location unknown");
assert(!isa<UndefinedVal>(L) && "location undefined");