diff options
-rw-r--r-- | include/clang/Analysis/PathSensitive/Store.h | 21 | ||||
-rw-r--r-- | lib/Analysis/RegionStore.cpp | 84 | ||||
-rw-r--r-- | 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<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. //===----------------------------------------------------------------------===// 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<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(); |