diff options
author | Zhongxing Xu <xuzhongxing@gmail.com> | 2008-10-24 01:09:32 +0000 |
---|---|---|
committer | Zhongxing Xu <xuzhongxing@gmail.com> | 2008-10-24 01:09:32 +0000 |
commit | b1d542a46eb71f23dafb5ce60b68247f280beb41 (patch) | |
tree | f9f23eea030024c4b3859965d3fdfd220b2c8de9 /lib/Analysis/RegionStore.cpp | |
parent | 95c7b00fe857a61a19185483aa0d85492ec9e258 (diff) |
Added getLValueElement() to RegionStore. Only handle constant array for now.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@58058 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis/RegionStore.cpp')
-rw-r--r-- | lib/Analysis/RegionStore.cpp | 54 |
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"); |