From 48ce7deb86ffb1e028ac9a8e7cddffc32843c26c Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Mon, 6 Jul 2009 20:21:51 +0000 Subject: [PATCH] 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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@74851 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Analysis/PathSensitive/Store.h | 21 ++++- lib/Analysis/RegionStore.cpp | 84 +------------------- lib/Analysis/Store.cpp | 82 ++++++++++++++++++- 3 files changed, 101 insertions(+), 86 deletions(-) diff --git a/include/clang/Analysis/PathSensitive/Store.h b/include/clang/Analysis/PathSensitive/Store.h index 40c01b46e8..44f13b37d9 100644 --- a/include/clang/Analysis/PathSensitive/Store.h +++ b/include/clang/Analysis/PathSensitive/Store.h @@ -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, diff --git a/lib/Analysis/RegionStore.cpp b/lib/Analysis/RegionStore.cpp index 23e8b738b6..1e95f174b5 100644 --- a/lib/Analysis/RegionStore.cpp +++ b/lib/Analysis/RegionStore.cpp @@ -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(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(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(ToTy.getTypePtr())->getPointeeType(); - - // Process region cast according to the kind of the region being cast. - - // FIXME: Need to handle arbitrary downcasts. - if (isa(R) || isa(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(R) || isa(R) || isa(R) - || isa(R) || isa(R)) { - // If the pointee type is incomplete, do not compute its size, and return - // the original region. - if (const RecordType *RT = dyn_cast(PointeeTy.getTypePtr())) { - const RecordDecl *D = RT->getDecl(); - if (!D->getDefinition(getContext())) - return CastResult(state, R); - } - - QualType ObjTy = cast(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(R)) { - return CastResult(state, R); - } - - assert(0 && "Unprocessed region."); - return 0; -} - //===----------------------------------------------------------------------===// // Pointer arithmetic. //===----------------------------------------------------------------------===// diff --git a/lib/Analysis/Store.cpp b/lib/Analysis/Store.cpp index deb546ae6a..5ca2da5057 100644 --- a/lib/Analysis/Store.cpp +++ b/lib/Analysis/Store.cpp @@ -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(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(ToTy.getTypePtr())->getPointeeType(); + + // Process region cast according to the kind of the region being cast. + + // FIXME: Need to handle arbitrary downcasts. + if (isa(R) || isa(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(R) || isa(R) || isa(R) + || isa(R) || isa(R)) { + // If the pointee type is incomplete, do not compute its size, and return + // the original region. + if (const RecordType *RT = dyn_cast(PointeeTy.getTypePtr())) { + const RecordDecl *D = RT->getDecl(); + if (!D->getDefinition(Ctx)) + return CastResult(state, R); + } + + QualType ObjTy = cast(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(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(); -- 2.40.0