Move the new 'CastRegion' implementation from RegionStoreManager to StoreManager

(its superclass). This will allow us to experiment with using the new CastRegion
with BasicStoreManager, and gradually phase out the old implementation.

llvm-svn: 74851
This commit is contained in:
Ted Kremenek 2009-07-06 20:21:51 +00:00
parent e64c196868
commit 9e010e11c3
3 changed files with 101 additions and 86 deletions

View File

@ -37,11 +37,12 @@ class StoreManager {
protected:
ValueManager &ValMgr;
GRStateManager &StateMgr;
const bool UseNewCastRegion;
/// MRMgr - Manages region objects associated with this StoreManager.
MemRegionManager &MRMgr;
StoreManager(GRStateManager &stateMgr);
StoreManager(GRStateManager &stateMgr, bool useNewCastRegion = false);
protected:
virtual const GRState *AddRegionView(const GRState *state,
@ -133,8 +134,22 @@ public:
/// CastRegion - Used by GRExprEngine::VisitCast to handle casts from
/// a MemRegion* to a specific location type. 'R' is the region being
/// casted and 'CastToTy' the result type of the cast.
virtual CastResult CastRegion(const GRState *state, const MemRegion *region,
QualType CastToTy);
CastResult CastRegion(const GRState *state, const MemRegion *region,
QualType CastToTy) {
return UseNewCastRegion ? NewCastRegion(state, region, CastToTy)
: OldCastRegion(state, region, CastToTy);
}
CastResult NewCastRegion(const GRState *state, const MemRegion *region,
QualType CastToTy);
CastResult OldCastRegion(const GRState *state, const MemRegion *region,
QualType CastToTy);
virtual const GRState *setCastType(const GRState *state, const MemRegion* R,
QualType T) {
return state;
}
/// EvalBinOp - Perform pointer arithmetic.
virtual SVal EvalBinOp(const GRState *state, BinaryOperator::Opcode Op,

View File

@ -167,7 +167,7 @@ class VISIBILITY_HIDDEN RegionStoreManager : public StoreManager {
public:
RegionStoreManager(GRStateManager& mgr, const RegionStoreFeatures &f)
: StoreManager(mgr),
: StoreManager(mgr, true),
Features(f),
RBFactory(mgr.getAllocator()),
RVFactory(mgr.getAllocator()),
@ -216,9 +216,6 @@ public:
/// casts from arrays to pointers.
SVal ArrayToPointer(Loc Array);
CastResult CastRegion(const GRState *state, const MemRegion* R,
QualType CastToTy);
SVal EvalBinOp(const GRState *state, BinaryOperator::Opcode Op,Loc L,
NonLoc R, QualType resultTy);
@ -327,7 +324,8 @@ public:
// Utility methods.
//===------------------------------------------------------------------===//
const GRState *setCastType(const GRState *state, const MemRegion* R, QualType T);
const GRState *setCastType(const GRState *state, const MemRegion* R,
QualType T);
static inline RegionBindingsTy GetRegionBindings(Store store) {
return RegionBindingsTy(static_cast<const RegionBindingsTy::TreeTy*>(store));
@ -638,82 +636,6 @@ SVal RegionStoreManager::ArrayToPointer(Loc Array) {
return loc::MemRegionVal(ER);
}
RegionStoreManager::CastResult
RegionStoreManager::CastRegion(const GRState *state, const MemRegion* R,
QualType CastToTy) {
ASTContext& Ctx = StateMgr.getContext();
// We need to know the real type of CastToTy.
QualType ToTy = Ctx.getCanonicalType(CastToTy);
// Check cast to ObjCQualifiedID type.
if (ToTy->isObjCQualifiedIdType()) {
// FIXME: Record the type information aside.
return CastResult(state, R);
}
// CodeTextRegion should be cast to only function pointer type.
if (isa<CodeTextRegion>(R)) {
assert(CastToTy->isFunctionPointerType() || CastToTy->isBlockPointerType()
|| (CastToTy->isPointerType()
&& CastToTy->getAsPointerType()->getPointeeType()->isVoidType()));
return CastResult(state, R);
}
// Now assume we are casting from pointer to pointer. Other cases should
// already be handled.
QualType PointeeTy = cast<PointerType>(ToTy.getTypePtr())->getPointeeType();
// Process region cast according to the kind of the region being cast.
// FIXME: Need to handle arbitrary downcasts.
if (isa<SymbolicRegion>(R) || isa<AllocaRegion>(R)) {
state = setCastType(state, R, ToTy);
return CastResult(state, R);
}
// VarRegion, ElementRegion, and FieldRegion has an inherent type. Normally
// they should not be cast. We only layer an ElementRegion when the cast-to
// pointee type is of smaller size. In other cases, we return the original
// VarRegion.
if (isa<VarRegion>(R) || isa<ElementRegion>(R) || isa<FieldRegion>(R)
|| isa<ObjCIvarRegion>(R) || isa<CompoundLiteralRegion>(R)) {
// If the pointee type is incomplete, do not compute its size, and return
// the original region.
if (const RecordType *RT = dyn_cast<RecordType>(PointeeTy.getTypePtr())) {
const RecordDecl *D = RT->getDecl();
if (!D->getDefinition(getContext()))
return CastResult(state, R);
}
QualType ObjTy = cast<TypedRegion>(R)->getValueType(getContext());
uint64_t PointeeTySize = getContext().getTypeSize(PointeeTy);
uint64_t ObjTySize = getContext().getTypeSize(ObjTy);
if ((PointeeTySize > 0 && PointeeTySize < ObjTySize) ||
(ObjTy->isAggregateType() && PointeeTy->isScalarType()) ||
ObjTySize == 0 /* R has 'void*' type. */) {
// Record the cast type of the region.
state = setCastType(state, R, ToTy);
SVal Idx = ValMgr.makeZeroArrayIndex();
ElementRegion* ER = MRMgr.getElementRegion(PointeeTy, Idx,R,getContext());
return CastResult(state, ER);
} else {
state = setCastType(state, R, ToTy);
return CastResult(state, R);
}
}
if (isa<ObjCObjectRegion>(R)) {
return CastResult(state, R);
}
assert(0 && "Unprocessed region.");
return 0;
}
//===----------------------------------------------------------------------===//
// Pointer arithmetic.
//===----------------------------------------------------------------------===//

View File

@ -16,13 +16,91 @@
using namespace clang;
StoreManager::StoreManager(GRStateManager &stateMgr)
StoreManager::StoreManager(GRStateManager &stateMgr, bool useNewCastRegion)
: ValMgr(stateMgr.getValueManager()),
StateMgr(stateMgr),
UseNewCastRegion(useNewCastRegion),
MRMgr(ValMgr.getRegionManager()) {}
StoreManager::CastResult
StoreManager::CastRegion(const GRState* state, const MemRegion* R,
StoreManager::NewCastRegion(const GRState *state, const MemRegion* R,
QualType CastToTy) {
ASTContext& Ctx = StateMgr.getContext();
// We need to know the real type of CastToTy.
QualType ToTy = Ctx.getCanonicalType(CastToTy);
// Check cast to ObjCQualifiedID type.
if (ToTy->isObjCQualifiedIdType()) {
// FIXME: Record the type information aside.
return CastResult(state, R);
}
// CodeTextRegion should be cast to only function pointer type.
if (isa<CodeTextRegion>(R)) {
assert(CastToTy->isFunctionPointerType() || CastToTy->isBlockPointerType()
|| (CastToTy->isPointerType()
&& CastToTy->getAsPointerType()->getPointeeType()->isVoidType()));
return CastResult(state, R);
}
// Now assume we are casting from pointer to pointer. Other cases should
// already be handled.
QualType PointeeTy = cast<PointerType>(ToTy.getTypePtr())->getPointeeType();
// Process region cast according to the kind of the region being cast.
// FIXME: Need to handle arbitrary downcasts.
if (isa<SymbolicRegion>(R) || isa<AllocaRegion>(R)) {
state = setCastType(state, R, ToTy);
return CastResult(state, R);
}
// VarRegion, ElementRegion, and FieldRegion has an inherent type. Normally
// they should not be cast. We only layer an ElementRegion when the cast-to
// pointee type is of smaller size. In other cases, we return the original
// VarRegion.
if (isa<VarRegion>(R) || isa<ElementRegion>(R) || isa<FieldRegion>(R)
|| isa<ObjCIvarRegion>(R) || isa<CompoundLiteralRegion>(R)) {
// If the pointee type is incomplete, do not compute its size, and return
// the original region.
if (const RecordType *RT = dyn_cast<RecordType>(PointeeTy.getTypePtr())) {
const RecordDecl *D = RT->getDecl();
if (!D->getDefinition(Ctx))
return CastResult(state, R);
}
QualType ObjTy = cast<TypedRegion>(R)->getValueType(Ctx);
uint64_t PointeeTySize = Ctx.getTypeSize(PointeeTy);
uint64_t ObjTySize = Ctx.getTypeSize(ObjTy);
if ((PointeeTySize > 0 && PointeeTySize < ObjTySize) ||
(ObjTy->isAggregateType() && PointeeTy->isScalarType()) ||
ObjTySize == 0 /* R has 'void*' type. */) {
// Record the cast type of the region.
state = setCastType(state, R, ToTy);
SVal Idx = ValMgr.makeZeroArrayIndex();
ElementRegion* ER = MRMgr.getElementRegion(PointeeTy, Idx,R, Ctx);
return CastResult(state, ER);
} else {
state = setCastType(state, R, ToTy);
return CastResult(state, R);
}
}
if (isa<ObjCObjectRegion>(R)) {
return CastResult(state, R);
}
assert(0 && "Unprocessed region.");
return 0;
}
StoreManager::CastResult
StoreManager::OldCastRegion(const GRState* state, const MemRegion* R,
QualType CastToTy) {
ASTContext& Ctx = StateMgr.getContext();