diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2012-07-30 23:48:14 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2012-07-30 23:48:14 +0000 |
commit | dd25e80a6d67485173fe295f54418e05764cc8cb (patch) | |
tree | ccd40b5d355bc82daca11131956ca70c8f01bae2 /lib/Sema/SemaDeclCXX.cpp | |
parent | 57c033621dacd8720ac9ff65a09025f14f70e22f (diff) |
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.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@161008 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaDeclCXX.cpp')
-rw-r--r-- | lib/Sema/SemaDeclCXX.cpp | 34 |
1 files changed, 26 insertions, 8 deletions
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index 9c4272de0c..fae0b165ce 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -4007,19 +4007,37 @@ computeImplicitExceptionSpec(Sema &S, SourceLocation Loc, CXXMethodDecl *MD) { 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) { const FunctionProtoType *FPT = MD->getType()->castAs<FunctionProtoType>(); if (FPT->getExceptionSpecType() != EST_Unevaluated) return; - // Evaluate the exception specification and update the type of the special - // member to use it. - FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo(); - computeImplicitExceptionSpec(*this, Loc, MD).getEPI(EPI); - const FunctionProtoType *NewFPT = cast<FunctionProtoType>( - Context.getFunctionType(FPT->getResultType(), FPT->arg_type_begin(), - FPT->getNumArgs(), EPI)); - MD->setType(QualType(NewFPT, 0)); + // Evaluate the exception specification. + ImplicitExceptionSpecification ExceptSpec = + computeImplicitExceptionSpec(*this, Loc, MD); + + // Update the type of the special member to use it. + updateExceptionSpec(*this, MD, FPT, ExceptSpec); + + // 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); |