diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp | 15 |
1 files changed, 14 insertions, 1 deletions
diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp index 6445b9df5a5..dd4345784b3 100644 --- a/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp +++ b/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp @@ -604,6 +604,7 @@ void ExprEngine::VisitCXXDestructor(QualType ObjectType, ExplodedNode *Pred, ExplodedNodeSet &Dst, const EvalCallOptions &CallOpts) { + assert(S && "A destructor without a trigger!"); const LocationContext *LCtx = Pred->getLocationContext(); ProgramStateRef State = Pred->getState(); @@ -611,6 +612,19 @@ void ExprEngine::VisitCXXDestructor(QualType ObjectType, assert(RecordDecl && "Only CXXRecordDecls should have destructors"); const CXXDestructorDecl *DtorDecl = RecordDecl->getDestructor(); + // FIXME: There should always be a Decl, otherwise the destructor call + // shouldn't have been added to the CFG in the first place. + if (!DtorDecl) { + // Skip the invalid destructor. We cannot simply return because + // it would interrupt the analysis instead. + static SimpleProgramPointTag T("ExprEngine", "SkipInvalidDestructor"); + // FIXME: PostImplicitCall with a null decl may crash elsewhere anyway. + PostImplicitCall PP(/*Decl=*/nullptr, S->getEndLoc(), LCtx, &T); + NodeBuilder Bldr(Pred, Dst, *currBldrCtx); + Bldr.generateNode(PP, Pred->getState(), Pred); + return; + } + CallEventManager &CEMgr = getStateManager().getCallEventManager(); CallEventRef<CXXDestructorCall> Call = CEMgr.getCXXDestructorCall(DtorDecl, S, Dest, IsBaseDtor, State, LCtx); @@ -629,7 +643,6 @@ void ExprEngine::VisitCXXDestructor(QualType ObjectType, I != E; ++I) defaultEvalCall(Bldr, *I, *Call, CallOpts); - ExplodedNodeSet DstPostCall; getCheckerManager().runCheckersForPostCall(Dst, DstInvalidated, *Call, *this); } |