diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Checker/GRExprEngine.cpp | 18 | ||||
-rw-r--r-- | lib/Checker/MemRegion.cpp | 25 | ||||
-rw-r--r-- | lib/Checker/RegionStore.cpp | 12 |
3 files changed, 52 insertions, 3 deletions
diff --git a/lib/Checker/GRExprEngine.cpp b/lib/Checker/GRExprEngine.cpp index 4121144fad..f541a7ece4 100644 --- a/lib/Checker/GRExprEngine.cpp +++ b/lib/Checker/GRExprEngine.cpp @@ -2688,8 +2688,7 @@ void GRExprEngine::VisitCast(const CastExpr *CastE, const Expr *Ex, case CK_IntegralComplexToFloatingComplex: case CK_AnyPointerToObjCPointerCast: case CK_AnyPointerToBlockPointerCast: - case CK_DerivedToBase: - case CK_UncheckedDerivedToBase: + case CK_ObjCObjectLValueCast: { // Delegate to SValuator to process. for (ExplodedNodeSet::iterator I = S2.begin(), E = S2.end(); I != E; ++I) { @@ -2702,7 +2701,20 @@ void GRExprEngine::VisitCast(const CastExpr *CastE, const Expr *Ex, } return; } - + + case CK_DerivedToBase: + case CK_UncheckedDerivedToBase: + // For DerivedToBase cast, delegate to the store manager. + for (ExplodedNodeSet::iterator I = S2.begin(), E = S2.end(); I != E; ++I) { + ExplodedNode *node = *I; + const GRState *state = GetState(node); + SVal val = state->getSVal(Ex); + val = getStoreManager().evalDerivedToBase(val, T); + state = state->BindExpr(CastE, val); + MakeNode(Dst, CastE, node, state); + } + return; + // Various C++ casts that are not handled yet. case CK_Dynamic: case CK_ToUnion: diff --git a/lib/Checker/MemRegion.cpp b/lib/Checker/MemRegion.cpp index 4414c1a57a..366a574683 100644 --- a/lib/Checker/MemRegion.cpp +++ b/lib/Checker/MemRegion.cpp @@ -218,6 +218,10 @@ DefinedOrUnknownSVal StringRegion::getExtent(ValueManager& ValMgr) const { return ValMgr.makeIntVal(getStringLiteral()->getByteLength()+1, SizeTy); } +QualType CXXBaseObjectRegion::getValueType() const { + return QualType(decl->getTypeForDecl(), 0); +} + //===----------------------------------------------------------------------===// // FoldingSet profiling. //===----------------------------------------------------------------------===// @@ -367,6 +371,17 @@ void CXXObjectRegion::Profile(llvm::FoldingSetNodeID &ID) const { ProfileRegion(ID, Ex, getSuperRegion()); } +void CXXBaseObjectRegion::ProfileRegion(llvm::FoldingSetNodeID &ID, + const CXXRecordDecl *decl, + const MemRegion *sReg) { + ID.AddPointer(decl); + ID.AddPointer(sReg); +} + +void CXXBaseObjectRegion::Profile(llvm::FoldingSetNodeID &ID) const { + ProfileRegion(ID, decl, superRegion); +} + //===----------------------------------------------------------------------===// // Region pretty-printing. //===----------------------------------------------------------------------===// @@ -411,6 +426,10 @@ void CXXObjectRegion::dumpToStream(llvm::raw_ostream &os) const { os << "temp_object"; } +void CXXBaseObjectRegion::dumpToStream(llvm::raw_ostream &os) const { + os << "base " << decl->getName(); +} + void CXXThisRegion::dumpToStream(llvm::raw_ostream &os) const { os << "this"; } @@ -687,6 +706,12 @@ MemRegionManager::getCXXObjectRegion(Expr const *E, return getSubRegion<CXXObjectRegion>(E, getStackLocalsRegion(SFC)); } +const CXXBaseObjectRegion * +MemRegionManager::getCXXBaseObjectRegion(const CXXRecordDecl *decl, + const MemRegion *superRegion) { + return getSubRegion<CXXBaseObjectRegion>(decl, superRegion); +} + const CXXThisRegion* MemRegionManager::getCXXThisRegion(QualType thisPointerTy, const LocationContext *LC) { diff --git a/lib/Checker/RegionStore.cpp b/lib/Checker/RegionStore.cpp index e5b1bca5d8..59c8730009 100644 --- a/lib/Checker/RegionStore.cpp +++ b/lib/Checker/RegionStore.cpp @@ -224,6 +224,9 @@ public: /// casts from arrays to pointers. SVal ArrayToPointer(Loc Array); + /// For DerivedToBase casts, create a CXXBaseObjectRegion and return it. + virtual SVal evalDerivedToBase(SVal derived, QualType basePtrType); + SVal EvalBinOp(BinaryOperator::Opcode Op,Loc L, NonLoc R, QualType resultTy); Store getInitialStore(const LocationContext *InitLoc) { @@ -804,6 +807,14 @@ SVal RegionStoreManager::ArrayToPointer(Loc Array) { return loc::MemRegionVal(MRMgr.getElementRegion(T, ZeroIdx, ArrayR, Ctx)); } +SVal RegionStoreManager::evalDerivedToBase(SVal derived, QualType basePtrType) { + const CXXRecordDecl *baseDecl = basePtrType->getCXXRecordDeclForPointerType(); + assert(baseDecl && "not a CXXRecordDecl?"); + loc::MemRegionVal &derivedRegVal = cast<loc::MemRegionVal>(derived); + const MemRegion *baseReg = + MRMgr.getCXXBaseObjectRegion(baseDecl, derivedRegVal.getRegion()); + return loc::MemRegionVal(baseReg); +} //===----------------------------------------------------------------------===// // Pointer arithmetic. //===----------------------------------------------------------------------===// @@ -869,6 +880,7 @@ SVal RegionStoreManager::EvalBinOp(BinaryOperator::Opcode Op, Loc L, NonLoc R, case MemRegion::FieldRegionKind: case MemRegion::ObjCIvarRegionKind: case MemRegion::CXXObjectRegionKind: + case MemRegion::CXXBaseObjectRegionKind: return UnknownVal(); case MemRegion::FunctionTextRegionKind: |