diff options
author | Sebastian Redl <sebastian.redl@getdesigned.at> | 2011-05-19 05:13:44 +0000 |
---|---|---|
committer | Sebastian Redl <sebastian.redl@getdesigned.at> | 2011-05-19 05:13:44 +0000 |
commit | 623ea82a6bc65fd28fe84a27e27afb914ad6e5f8 (patch) | |
tree | 572a12ccfc6c7f6de8f44ecc5a8ca615d7f7d716 /clang/lib/Sema/SemaDeclCXX.cpp | |
parent | 9eb5a410bdb633c356acdb349299ab38e2e44b08 (diff) | |
download | bcm5719-llvm-623ea82a6bc65fd28fe84a27e27afb914ad6e5f8.tar.gz bcm5719-llvm-623ea82a6bc65fd28fe84a27e27afb914ad6e5f8.zip |
Reapply r121528, fixing PR9941 by delaying the exception specification check for destructors until the class is complete and destructors have been adjusted.
llvm-svn: 131632
Diffstat (limited to 'clang/lib/Sema/SemaDeclCXX.cpp')
-rw-r--r-- | clang/lib/Sema/SemaDeclCXX.cpp | 41 |
1 files changed, 35 insertions, 6 deletions
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 1227c4eff2b..c6a0490c247 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -6214,18 +6214,18 @@ Sema::ComputeDefaultedDtorExceptionSpec(CXXRecordDecl *ClassDecl) { if (const RecordType *BaseType = B->getType()->getAs<RecordType>()) ExceptSpec.CalledDecl( - LookupDestructor(cast<CXXRecordDecl>(BaseType->getDecl()))); + LookupDestructor(cast<CXXRecordDecl>(BaseType->getDecl()))); } - + // Virtual base-class destructors. for (CXXRecordDecl::base_class_iterator B = ClassDecl->vbases_begin(), BEnd = ClassDecl->vbases_end(); B != BEnd; ++B) { if (const RecordType *BaseType = B->getType()->getAs<RecordType>()) ExceptSpec.CalledDecl( - LookupDestructor(cast<CXXRecordDecl>(BaseType->getDecl()))); + LookupDestructor(cast<CXXRecordDecl>(BaseType->getDecl()))); } - + // Field destructors. for (RecordDecl::field_iterator F = ClassDecl->field_begin(), FEnd = ClassDecl->field_end(); @@ -6233,7 +6233,7 @@ Sema::ComputeDefaultedDtorExceptionSpec(CXXRecordDecl *ClassDecl) { if (const RecordType *RecordTy = Context.getBaseElementType(F->getType())->getAs<RecordType>()) ExceptSpec.CalledDecl( - LookupDestructor(cast<CXXRecordDecl>(RecordTy->getDecl()))); + LookupDestructor(cast<CXXRecordDecl>(RecordTy->getDecl()))); } return ExceptSpec; @@ -6246,7 +6246,7 @@ CXXDestructorDecl *Sema::DeclareImplicitDestructor(CXXRecordDecl *ClassDecl) { // inline public member of its class. ImplicitExceptionSpecification Spec = - ComputeDefaultedDtorExceptionSpec(ClassDecl); + ComputeDefaultedDtorExceptionSpec(ClassDecl); FunctionProtoType::ExtProtoInfo EPI = Spec.getEPI(); // Create the actual destructor declaration. @@ -6321,6 +6321,35 @@ void Sema::DefineImplicitDestructor(SourceLocation CurrentLocation, } } +void Sema::AdjustDestructorExceptionSpec(CXXRecordDecl *classDecl, + CXXDestructorDecl *destructor) { + // C++11 [class.dtor]p3: + // A declaration of a destructor that does not have an exception- + // specification is implicitly considered to have the same exception- + // specification as an implicit declaration. + const FunctionProtoType *dtorType = destructor->getType()-> + getAs<FunctionProtoType>(); + if (dtorType->hasExceptionSpec()) + return; + + ImplicitExceptionSpecification exceptSpec = + ComputeDefaultedDtorExceptionSpec(classDecl); + + // Replace the destructor's type. + FunctionProtoType::ExtProtoInfo epi; + epi.ExceptionSpecType = exceptSpec.getExceptionSpecType(); + epi.NumExceptions = exceptSpec.size(); + epi.Exceptions = exceptSpec.data(); + QualType ty = Context.getFunctionType(Context.VoidTy, 0, 0, epi); + + destructor->setType(ty); + + // FIXME: If the destructor has a body that could throw, and the newly created + // spec doesn't allow exceptions, we should emit a warning, because this + // change in behavior can break conforming C++03 programs at runtime. + // However, we don't have a body yet, so it needs to be done somewhere else. +} + /// \brief Builds a statement that copies the given entity from \p From to /// \c To. /// |