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 | a8d2cbe47fe575976406f1637964e3d42d8cd3f5 (patch) | |
| tree | 8b0492a10c48a42a2e02d56328f421d0ca65373a | |
| parent | 8b531d2754ce2d15916969f712589571407dc26b (diff) | |
| download | bcm5719-llvm-a8d2cbe47fe575976406f1637964e3d42d8cd3f5.tar.gz bcm5719-llvm-a8d2cbe47fe575976406f1637964e3d42d8cd3f5.zip | |
Added getLValueElement() to RegionStore. Only handle constant array for now.
llvm-svn: 58058
| -rw-r--r-- | clang/lib/Analysis/RegionStore.cpp | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/clang/lib/Analysis/RegionStore.cpp b/clang/lib/Analysis/RegionStore.cpp index 1bd29add306..f64ed76be72 100644 --- a/clang/lib/Analysis/RegionStore.cpp +++ b/clang/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"); |

