diff options
| author | Artem Dergachev <artem.dergachev@gmail.com> | 2019-01-18 23:05:07 +0000 |
|---|---|---|
| committer | Artem Dergachev <artem.dergachev@gmail.com> | 2019-01-18 23:05:07 +0000 |
| commit | 097a0497400f25c7c296feba0d148523bd37f29e (patch) | |
| tree | 5541615ae38b91ad4517f57c7e83adcc02a25da4 /clang/lib | |
| parent | c2c47f24f53a064d141eb5ea62ecd76d636edf77 (diff) | |
| download | bcm5719-llvm-097a0497400f25c7c296feba0d148523bd37f29e.tar.gz bcm5719-llvm-097a0497400f25c7c296feba0d148523bd37f29e.zip | |
[analyzer] pr37688: Fix a crash upon evaluating a deleted destructor of a union.
Add a defensive check against an invalid destructor in the CFG.
Unions with fields with destructors have their own destructor implicitly
deleted. Due to a bug in the CFG we're still trying to evaluate them
at the end of the object's lifetime and crash because we are unable
to find the destructor's declaration.
rdar://problem/47362608
Differential Revision: https://reviews.llvm.org/D56899
llvm-svn: 351610
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); } |

