forked from OSchip/llvm-project
PR13479: If we see the definition of an out-of-line destructor in C++11, be
sure to update the exception specification on the declaration as well as the definition. If we're building in -fno-exceptions mode, nothing else will trigger it to be updated. llvm-svn: 161008
This commit is contained in:
parent
535a23c38b
commit
7f78227ce9
|
@ -4007,19 +4007,37 @@ computeImplicitExceptionSpec(Sema &S, SourceLocation Loc, CXXMethodDecl *MD) {
|
||||||
llvm_unreachable("only special members have implicit exception specs");
|
llvm_unreachable("only special members have implicit exception specs");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
updateExceptionSpec(Sema &S, FunctionDecl *FD, const FunctionProtoType *FPT,
|
||||||
|
const Sema::ImplicitExceptionSpecification &ExceptSpec) {
|
||||||
|
FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo();
|
||||||
|
ExceptSpec.getEPI(EPI);
|
||||||
|
const FunctionProtoType *NewFPT = cast<FunctionProtoType>(
|
||||||
|
S.Context.getFunctionType(FPT->getResultType(), FPT->arg_type_begin(),
|
||||||
|
FPT->getNumArgs(), EPI));
|
||||||
|
FD->setType(QualType(NewFPT, 0));
|
||||||
|
}
|
||||||
|
|
||||||
void Sema::EvaluateImplicitExceptionSpec(SourceLocation Loc, CXXMethodDecl *MD) {
|
void Sema::EvaluateImplicitExceptionSpec(SourceLocation Loc, CXXMethodDecl *MD) {
|
||||||
const FunctionProtoType *FPT = MD->getType()->castAs<FunctionProtoType>();
|
const FunctionProtoType *FPT = MD->getType()->castAs<FunctionProtoType>();
|
||||||
if (FPT->getExceptionSpecType() != EST_Unevaluated)
|
if (FPT->getExceptionSpecType() != EST_Unevaluated)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Evaluate the exception specification and update the type of the special
|
// Evaluate the exception specification.
|
||||||
// member to use it.
|
ImplicitExceptionSpecification ExceptSpec =
|
||||||
FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo();
|
computeImplicitExceptionSpec(*this, Loc, MD);
|
||||||
computeImplicitExceptionSpec(*this, Loc, MD).getEPI(EPI);
|
|
||||||
const FunctionProtoType *NewFPT = cast<FunctionProtoType>(
|
// Update the type of the special member to use it.
|
||||||
Context.getFunctionType(FPT->getResultType(), FPT->arg_type_begin(),
|
updateExceptionSpec(*this, MD, FPT, ExceptSpec);
|
||||||
FPT->getNumArgs(), EPI));
|
|
||||||
MD->setType(QualType(NewFPT, 0));
|
// A user-provided destructor can be defined outside the class. When that
|
||||||
|
// happens, be sure to update the exception specification on both
|
||||||
|
// declarations.
|
||||||
|
const FunctionProtoType *CanonicalFPT =
|
||||||
|
MD->getCanonicalDecl()->getType()->castAs<FunctionProtoType>();
|
||||||
|
if (CanonicalFPT->getExceptionSpecType() == EST_Unevaluated)
|
||||||
|
updateExceptionSpec(*this, MD->getCanonicalDecl(),
|
||||||
|
CanonicalFPT, ExceptSpec);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool isImplicitCopyCtorArgConst(Sema &S, CXXRecordDecl *ClassDecl);
|
static bool isImplicitCopyCtorArgConst(Sema &S, CXXRecordDecl *ClassDecl);
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
// RUN: %clang_cc1 -emit-llvm-only %s -std=c++11
|
||||||
|
|
||||||
|
// PR13479: don't crash with -fno-exceptions.
|
||||||
|
namespace {
|
||||||
|
struct SchedulePostRATDList {
|
||||||
|
virtual ~SchedulePostRATDList();
|
||||||
|
};
|
||||||
|
|
||||||
|
SchedulePostRATDList::~SchedulePostRATDList() {}
|
||||||
|
|
||||||
|
SchedulePostRATDList Scheduler;
|
||||||
|
}
|
Loading…
Reference in New Issue