Initial support for pointer arithmetic. Only support concrete indexes and
offsets for now. llvm-svn: 65814
This commit is contained in:
parent
b3921bf12e
commit
e7d1493216
|
|
@ -112,6 +112,11 @@ public:
|
||||||
/// casted and 'CastToTy' the result type of the cast.
|
/// casted and 'CastToTy' the result type of the cast.
|
||||||
virtual CastResult CastRegion(const GRState* state, const MemRegion* R,
|
virtual CastResult CastRegion(const GRState* state, const MemRegion* R,
|
||||||
QualType CastToTy) = 0;
|
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
|
/// getSelfRegion - Returns the region for the 'self' (Objective-C) or
|
||||||
/// 'this' object (C++). When used when analyzing a normal function this
|
/// 'this' object (C++). When used when analyzing a normal function this
|
||||||
|
|
|
||||||
|
|
@ -265,7 +265,8 @@ SVal GRSimpleVals::EvalBinOp(GRExprEngine& Eng, BinaryOperator::Opcode Op,
|
||||||
|
|
||||||
SVal GRSimpleVals::EvalBinOp(GRExprEngine& Eng, BinaryOperator::Opcode Op,
|
SVal GRSimpleVals::EvalBinOp(GRExprEngine& Eng, BinaryOperator::Opcode Op,
|
||||||
Loc L, NonLoc R) {
|
Loc L, NonLoc R) {
|
||||||
return UnknownVal();
|
// Delegate pointer arithmetic to store manager.
|
||||||
|
return Eng.getStoreManager().EvalBinOp(Op, L, R);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Equality operators for Locs.
|
// Equality operators for Locs.
|
||||||
|
|
|
||||||
|
|
@ -170,6 +170,8 @@ public:
|
||||||
CastResult CastRegion(const GRState* state, const MemRegion* R,
|
CastResult CastRegion(const GRState* state, const MemRegion* R,
|
||||||
QualType CastToTy);
|
QualType CastToTy);
|
||||||
|
|
||||||
|
SVal EvalBinOp(BinaryOperator::Opcode Op, Loc L, NonLoc R);
|
||||||
|
|
||||||
/// The high level logic for this method is this:
|
/// The high level logic for this method is this:
|
||||||
/// Retrieve (L)
|
/// Retrieve (L)
|
||||||
/// if L has binding
|
/// if L has binding
|
||||||
|
|
@ -551,6 +553,33 @@ RegionStoreManager::CastRegion(const GRState* state, const MemRegion* R,
|
||||||
return CastResult(AddRegionView(state, ViewR, R), ViewR);
|
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<loc::MemRegionVal>(L)) {
|
||||||
|
return UnknownVal();
|
||||||
|
}
|
||||||
|
|
||||||
|
const MemRegion* MR = cast<loc::MemRegionVal>(L).getRegion();
|
||||||
|
|
||||||
|
const ElementRegion* ER = cast<ElementRegion>(MR);
|
||||||
|
SVal Idx = ER->getIndex();
|
||||||
|
|
||||||
|
nonloc::ConcreteInt* Base = dyn_cast<nonloc::ConcreteInt>(&Idx);
|
||||||
|
nonloc::ConcreteInt* Offset = dyn_cast<nonloc::ConcreteInt>(&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) {
|
SVal RegionStoreManager::Retrieve(const GRState* St, Loc L, QualType T) {
|
||||||
assert(!isa<UnknownVal>(L) && "location unknown");
|
assert(!isa<UnknownVal>(L) && "location unknown");
|
||||||
assert(!isa<UndefinedVal>(L) && "location undefined");
|
assert(!isa<UndefinedVal>(L) && "location undefined");
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue