Restructure RegionStoreManager::EvalBinOp() as a switch dispatch over different

MemRegion kinds. This allows the compiler to identify what MemRegions we don't
handle for pointer arithmetic.

llvm-svn: 75326
This commit is contained in:
Ted Kremenek 2009-07-11 00:58:27 +00:00
parent 55179ca5aa
commit f6f0461a38
1 changed files with 58 additions and 32 deletions

View File

@ -665,43 +665,69 @@ SVal RegionStoreManager::EvalBinOp(const GRState *state,
const MemRegion* MR = cast<loc::MemRegionVal>(L).getRegion(); const MemRegion* MR = cast<loc::MemRegionVal>(L).getRegion();
const ElementRegion *ER = 0; const ElementRegion *ER = 0;
// If the operand is a symbolic or alloca region, create the first element switch (MR->getKind()) {
// region on it. case MemRegion::SymbolicRegionKind: {
if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(MR)) { const SymbolicRegion *SR = cast<SymbolicRegion>(MR);
QualType T; QualType T;
// If the SymbolicRegion was cast to another type, use that type. // If the SymbolicRegion was cast to another type, use that type.
if (const QualType *t = state->get<RegionCasts>(SR)) { if (const QualType *t = state->get<RegionCasts>(SR))
T = *t; T = *t;
} else { else {
// Otherwise use the symbol's type. // Otherwise use the symbol's type.
SymbolRef Sym = SR->getSymbol(); SymbolRef Sym = SR->getSymbol();
T = Sym->getType(getContext()); T = Sym->getType(getContext());
}
QualType EleTy = T->getAsPointerType()->getPointeeType();
SVal ZeroIdx = ValMgr.makeZeroArrayIndex();
ER = MRMgr.getElementRegion(EleTy, ZeroIdx, SR, getContext());
break;
}
case MemRegion::AllocaRegionKind: {
// Get the alloca region's current cast type.
const AllocaRegion *AR = cast<AllocaRegion>(MR);
QualType T = *(state->get<RegionCasts>(AR));
QualType EleTy = T->getAsPointerType()->getPointeeType();
SVal ZeroIdx = ValMgr.makeZeroArrayIndex();
ER = MRMgr.getElementRegion(EleTy, ZeroIdx, AR, getContext());
break;
} }
QualType EleTy = T->getAsPointerType()->getPointeeType();
SVal ZeroIdx = ValMgr.makeZeroArrayIndex(); case MemRegion::ElementRegionKind: {
ER = MRMgr.getElementRegion(EleTy, ZeroIdx, SR, getContext()); ER = cast<ElementRegion>(MR);
} break;
else if (const AllocaRegion *AR = dyn_cast<AllocaRegion>(MR)) { }
// Get the alloca region's current cast type.
// Not yet handled.
case MemRegion::VarRegionKind:
GRStateTrait<RegionCasts>::lookup_type T = state->get<RegionCasts>(AR); case MemRegion::StringRegionKind:
assert(T && "alloca region has no type."); case MemRegion::CompoundLiteralRegionKind:
QualType EleTy = cast<PointerType>(T->getTypePtr())->getPointeeType(); case MemRegion::FieldRegionKind:
SVal ZeroIdx = ValMgr.makeZeroArrayIndex(); case MemRegion::ObjCObjectRegionKind:
ER = MRMgr.getElementRegion(EleTy, ZeroIdx, AR, getContext()); case MemRegion::ObjCIvarRegionKind:
} return UnknownVal();
else if (isa<FieldRegion>(MR)) {
// Not track pointer arithmetic on struct fields. // TypedViewRegion will soon be removed.
return UnknownVal(); case MemRegion::TypedViewRegionKind:
} return UnknownVal();
else {
ER = cast<ElementRegion>(MR); case MemRegion::CodeTextRegionKind:
// Technically this can happen if people do funny things with casts.
return UnknownVal();
case MemRegion::MemSpaceRegionKind:
assert(0 && "Cannot perform pointer arithmetic on a MemSpace");
return UnknownVal();
case MemRegion::BEG_DECL_REGIONS:
case MemRegion::END_DECL_REGIONS:
case MemRegion::BEG_TYPED_REGIONS:
case MemRegion::END_TYPED_REGIONS:
assert(0 && "Infeasible region");
return UnknownVal();
} }
SVal Idx = ER->getIndex(); SVal Idx = ER->getIndex();
nonloc::ConcreteInt* Base = dyn_cast<nonloc::ConcreteInt>(&Idx); nonloc::ConcreteInt* Base = dyn_cast<nonloc::ConcreteInt>(&Idx);
nonloc::ConcreteInt* Offset = dyn_cast<nonloc::ConcreteInt>(&R); nonloc::ConcreteInt* Offset = dyn_cast<nonloc::ConcreteInt>(&R);