From 94aa6c16e7404b2ff83a6f0ae7db8a758d389fc4 Mon Sep 17 00:00:00 2001 From: Zhongxing Xu Date: Mon, 2 Mar 2009 07:52:23 +0000 Subject: [PATCH] Initial support for pointer arithmetic. Only support concrete indexes and offsets for now. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@65814 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Analysis/PathSensitive/Store.h | 5 ++++ lib/Analysis/GRSimpleVals.cpp | 3 +- lib/Analysis/RegionStore.cpp | 29 ++++++++++++++++++++ 3 files changed, 36 insertions(+), 1 deletion(-) diff --git a/include/clang/Analysis/PathSensitive/Store.h b/include/clang/Analysis/PathSensitive/Store.h index b8d6364388..ed30a8bca5 100644 --- a/include/clang/Analysis/PathSensitive/Store.h +++ b/include/clang/Analysis/PathSensitive/Store.h @@ -112,6 +112,11 @@ public: /// casted and 'CastToTy' the result type of the cast. virtual CastResult CastRegion(const GRState* state, const MemRegion* R, QualType CastToTy) = 0; + + /// EvalBinOp - Perform pointer arithmetic. + virtual SVal EvalBinOp(BinaryOperator::Opcode Op, Loc L, NonLoc R) { + return UnknownVal(); + } /// getSelfRegion - Returns the region for the 'self' (Objective-C) or /// 'this' object (C++). When used when analyzing a normal function this diff --git a/lib/Analysis/GRSimpleVals.cpp b/lib/Analysis/GRSimpleVals.cpp index d50876e5b3..90d9e57bfd 100644 --- a/lib/Analysis/GRSimpleVals.cpp +++ b/lib/Analysis/GRSimpleVals.cpp @@ -265,7 +265,8 @@ SVal GRSimpleVals::EvalBinOp(GRExprEngine& Eng, BinaryOperator::Opcode Op, SVal GRSimpleVals::EvalBinOp(GRExprEngine& Eng, BinaryOperator::Opcode Op, Loc L, NonLoc R) { - return UnknownVal(); + // Delegate pointer arithmetic to store manager. + return Eng.getStoreManager().EvalBinOp(Op, L, R); } // Equality operators for Locs. diff --git a/lib/Analysis/RegionStore.cpp b/lib/Analysis/RegionStore.cpp index e6e530bc0f..7ab54b8b25 100644 --- a/lib/Analysis/RegionStore.cpp +++ b/lib/Analysis/RegionStore.cpp @@ -170,6 +170,8 @@ public: CastResult CastRegion(const GRState* state, const MemRegion* R, QualType CastToTy); + SVal EvalBinOp(BinaryOperator::Opcode Op, Loc L, NonLoc R); + /// The high level logic for this method is this: /// Retrieve (L) /// if L has binding @@ -551,6 +553,33 @@ RegionStoreManager::CastRegion(const GRState* state, const MemRegion* R, return CastResult(AddRegionView(state, ViewR, R), ViewR); } +SVal RegionStoreManager::EvalBinOp(BinaryOperator::Opcode Op, Loc L, NonLoc R) { + // Assume the base location is MemRegionVal(ElementRegion). + + if (!isa(L)) { + return UnknownVal(); + } + + const MemRegion* MR = cast(L).getRegion(); + + const ElementRegion* ER = cast(MR); + SVal Idx = ER->getIndex(); + + nonloc::ConcreteInt* Base = dyn_cast(&Idx); + nonloc::ConcreteInt* Offset = dyn_cast(&R); + + // Only support concrete integer indexes for now. + if (Base && Offset) { + SVal NewIdx = Base->EvalBinOp(getBasicVals(), Op, *Offset); + + const MemRegion* NewER = MRMgr.getElementRegion(NewIdx, + ER->getArrayRegion()); + return Loc::MakeVal(NewER); + + } else + return UnknownVal(); +} + SVal RegionStoreManager::Retrieve(const GRState* St, Loc L, QualType T) { assert(!isa(L) && "location unknown"); assert(!isa(L) && "location undefined"); -- 2.40.0