From: Sean Hunt Date: Wed, 18 May 2011 20:57:11 +0000 (+0000) Subject: Revert r121528 as it breaks a simple testcase, which leads to, among X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=1d78032167c2f2d470e4270aadcb07ff71e6c7e1;p=clang Revert r121528 as it breaks a simple testcase, which leads to, among other things, libcxx not building. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@131573 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index fe14398f1b..d1487cc317 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -2644,13 +2644,6 @@ public: void DefineImplicitDestructor(SourceLocation CurrentLocation, CXXDestructorDecl *Destructor); - /// \brief Build an exception spec for destructors that don't have one. - /// - /// C++11 says that user-defined destructors with no exception spec get one - /// that looks as if the destructor was implicitly declared. - void AdjustDestructorExceptionSpec(CXXRecordDecl *ClassDecl, - CXXDestructorDecl *Destructor); - /// \brief Declare all inherited constructors for the given class. /// /// \param ClassDecl The class declaration into which the inherited diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index d93e5fa563..3ee1626f7e 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -4143,25 +4143,14 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC, // This is a C++ destructor declaration. if (DC->isRecord()) { R = CheckDestructorDeclarator(D, R, SC); - CXXRecordDecl *Record = cast(DC); - CXXDestructorDecl *NewDD = CXXDestructorDecl::Create(Context, Record, + NewFD = CXXDestructorDecl::Create(Context, + cast(DC), D.getSourceRange().getBegin(), NameInfo, R, TInfo, isInline, /*isImplicitlyDeclared=*/false); - NewFD = NewDD; isVirtualOkay = true; - - // If the class is complete, then we now create the implicit exception - // specification. If the class is incomplete or dependent, we can't do - // it yet. - if (getLangOptions().CPlusPlus0x && !Record->isDependentType() && - Record->getDefinition() && !Record->isBeingDefined() && - R->getAs()->getExceptionSpecType() == EST_None) { - AdjustDestructorExceptionSpec(Record, NewDD); - } - } else { Diag(D.getIdentifierLoc(), diag::err_destructor_not_member); @@ -8139,11 +8128,6 @@ void Sema::ActOnFields(Scope* S, Convs->setAccess(I, (*I)->getAccess()); if (!CXXRecord->isDependentType()) { - // Adjust user-defined destructor exception spec. - if (getLangOptions().CPlusPlus0x && - CXXRecord->hasUserDeclaredDestructor()) - AdjustDestructorExceptionSpec(CXXRecord,CXXRecord->getDestructor()); - // Add any implicitly-declared members to this class. AddImplicitlyDeclaredMembersToClass(CXXRecord); diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index e308956a37..9f146e9254 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -6222,18 +6222,18 @@ Sema::ComputeDefaultedDtorExceptionSpec(CXXRecordDecl *ClassDecl) { if (const RecordType *BaseType = B->getType()->getAs()) ExceptSpec.CalledDecl( - LookupDestructor(cast(BaseType->getDecl()))); + LookupDestructor(cast(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()) ExceptSpec.CalledDecl( - LookupDestructor(cast(BaseType->getDecl()))); + LookupDestructor(cast(BaseType->getDecl()))); } - + // Field destructors. for (RecordDecl::field_iterator F = ClassDecl->field_begin(), FEnd = ClassDecl->field_end(); @@ -6241,7 +6241,7 @@ Sema::ComputeDefaultedDtorExceptionSpec(CXXRecordDecl *ClassDecl) { if (const RecordType *RecordTy = Context.getBaseElementType(F->getType())->getAs()) ExceptSpec.CalledDecl( - LookupDestructor(cast(RecordTy->getDecl()))); + LookupDestructor(cast(RecordTy->getDecl()))); } return ExceptSpec; @@ -6254,7 +6254,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. @@ -6329,35 +6329,6 @@ 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(); - 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. /// diff --git a/test/CXX/special/class.dtor/p3-0x.cpp b/test/CXX/special/class.dtor/p3-0x.cpp deleted file mode 100644 index d4a9fdd867..0000000000 --- a/test/CXX/special/class.dtor/p3-0x.cpp +++ /dev/null @@ -1,127 +0,0 @@ -// RUN: %clang_cc1 -std=c++0x -fexceptions -fcxx-exceptions -emit-llvm -o - %s | FileCheck %s - -struct A { - ~A(); -}; - -struct B { - ~B() throw(int); -}; - -struct C { - B b; - ~C() {} -}; - -struct D { - ~D() noexcept(false); -}; - -struct E { - D d; - ~E() {} -}; - -void foo() { - A a; - C c; - E e; - // CHECK: invoke void @_ZN1ED1Ev - // CHECK: invoke void @_ZN1CD1Ev - // CHECK: call void @_ZN1AD1Ev -} - -struct F { - D d; - ~F(); -}; -F::~F() noexcept(false) {} - -struct G { - D d; - ~G(); -}; -G::~G() {} - -struct H { - B b; - ~H(); -}; -H::~H() throw(int) {} - -struct I { - B b; - ~I(); -}; -I::~I() {} - -// Template variants. - -template -struct TA { - ~TA(); -}; - -template -struct TB { - ~TB() throw(int); -}; - -template -struct TC { - TB b; - ~TC() {} -}; - -template -struct TD { - ~TD() noexcept(false); -}; - -template -struct TE { - TD d; - ~TE() {} -}; - -void tfoo() { - TA a; - TC c; - TE e; - // CHECK: invoke void @_ZN2TEIiED1Ev - // CHECK: invoke void @_ZN2TCIiED1Ev - // CHECK: call void @_ZN2TAIiED1Ev -} - -template -struct TF { - TD d; - ~TF(); -}; -template -TF::~TF() noexcept(false) {} - -template -struct TG { - TD d; - ~TG(); -}; -template -TG::~TG() {} - -template -struct TH { - TB b; - ~TH(); -}; -template -TH::~TH() {} - -void tinst() { - TF f; - TG g; - TH h; -} -// CHECK: define linkonce_odr void @_ZN2THIiED1Ev -// CHECK: _ZTIi -// CHECK: __cxa_call_unexpected diff --git a/test/CodeGenCXX/cxx0x-delegating-ctors.cpp b/test/CodeGenCXX/cxx0x-delegating-ctors.cpp index 15c8e7f5d8..f45a87c687 100644 --- a/test/CodeGenCXX/cxx0x-delegating-ctors.cpp +++ b/test/CodeGenCXX/cxx0x-delegating-ctors.cpp @@ -2,10 +2,10 @@ struct non_trivial { non_trivial(); - ~non_trivial() noexcept(false); + ~non_trivial(); }; non_trivial::non_trivial() {} -non_trivial::~non_trivial() noexcept(false) {} +non_trivial::~non_trivial() {} // We use a virtual base to ensure that the constructor // delegation optimization (complete->base) can't be diff --git a/test/CodeGenCXX/eh.cpp b/test/CodeGenCXX/eh.cpp index 88c32724b8..6c44c76129 100644 --- a/test/CodeGenCXX/eh.cpp +++ b/test/CodeGenCXX/eh.cpp @@ -159,7 +159,7 @@ namespace test8 { // CHECK-NEXT: bitcast // CHECK-NEXT: invoke void @_ZN5test81AC1ERKS0_( // CHECK: call i8* @__cxa_begin_catch - // CHECK-NEXT: call void @_ZN5test81AD1Ev( + // CHECK-NEXT: invoke void @_ZN5test81AD1Ev( // CHECK: call void @__cxa_end_catch() // CHECK: ret void } @@ -272,7 +272,7 @@ namespace test11 { // PR7686 namespace test12 { - struct A { ~A() noexcept(false); }; + struct A { ~A(); }; bool opaque(const A&); // CHECK: define void @_ZN6test124testEv() @@ -392,8 +392,8 @@ namespace test15 { } namespace test16 { - struct A { A(); ~A() noexcept(false); }; - struct B { int x; B(const A &); ~B() noexcept(false); }; + struct A { A(); ~A(); }; + struct B { int x; B(const A &); ~B(); }; void foo(); bool cond(); diff --git a/test/SemaCXX/pr9941.cpp b/test/SemaCXX/pr9941.cpp new file mode 100644 index 0000000000..ae744e3631 --- /dev/null +++ b/test/SemaCXX/pr9941.cpp @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s + +struct X +{ virtual ~X() {} }; + +struct Y : X +{ virtual ~Y() {} };