This and r155289 would make good candidates for porting to the branch. On Sat, Apr 21, 2012 at 11:42 AM, Richard Smith <richard-l...@metafoo.co.uk>wrote:
> Author: rsmith > Date: Sat Apr 21 13:42:51 2012 > New Revision: 155293 > > URL: http://llvm.org/viewvc/llvm-project?rev=155293&view=rev > Log: > Fix regression in r154844. If necessary, defer computing adjusted > destructor > exception specifications in C++11 until after we've parsed the exception > specifications for nested classes. > > Modified: > cfe/trunk/include/clang/Sema/Sema.h > cfe/trunk/lib/Parse/ParseDeclCXX.cpp > cfe/trunk/lib/Sema/SemaDecl.cpp > cfe/trunk/lib/Sema/SemaDeclCXX.cpp > cfe/trunk/test/SemaCXX/implicit-exception-spec.cpp > > Modified: cfe/trunk/include/clang/Sema/Sema.h > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=155293&r1=155292&r2=155293&view=diff > > ============================================================================== > --- cfe/trunk/include/clang/Sema/Sema.h (original) > +++ cfe/trunk/include/clang/Sema/Sema.h Sat Apr 21 13:42:51 2012 > @@ -331,6 +331,11 @@ > /// cycle detection at the end of the TU. > DelegatingCtorDeclsType DelegatingCtorDecls; > > + /// \brief All the destructors seen during a class definition that had > their > + /// exception spec computation delayed because it depended on an > unparsed > + /// exception spec. > + SmallVector<CXXDestructorDecl*, 2> DelayedDestructorExceptionSpecs; > + > /// \brief All the overriding destructors seen during a class definition > /// (there could be multiple due to nested classes) that had their > exception > /// spec checks delayed, plus the overridden destructor. > @@ -3203,7 +3208,8 @@ > /// 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); > + CXXDestructorDecl *Destructor, > + bool WasDelayed = false); > > /// \brief Declare all inherited constructors for the given class. > /// > @@ -4048,6 +4054,7 @@ > SourceLocation LBrac, > SourceLocation RBrac, > AttributeList *AttrList); > + void ActOnFinishCXXMemberDecls(); > > void ActOnReenterTemplateScope(Scope *S, Decl *Template); > void ActOnReenterDeclaratorTemplateScope(Scope *S, DeclaratorDecl *D); > > Modified: cfe/trunk/lib/Parse/ParseDeclCXX.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDeclCXX.cpp?rev=155293&r1=155292&r2=155293&view=diff > > ============================================================================== > --- cfe/trunk/lib/Parse/ParseDeclCXX.cpp (original) > +++ cfe/trunk/lib/Parse/ParseDeclCXX.cpp Sat Apr 21 13:42:51 2012 > @@ -2369,6 +2369,10 @@ > SourceLocation SavedPrevTokLocation = PrevTokLocation; > ParseLexedAttributes(getCurrentClass()); > ParseLexedMethodDeclarations(getCurrentClass()); > + > + // We've finished with all pending member declarations. > + Actions.ActOnFinishCXXMemberDecls(); > + > ParseLexedMemberInitializers(getCurrentClass()); > ParseLexedMethodDefs(getCurrentClass()); > PrevTokLocation = SavedPrevTokLocation; > > Modified: cfe/trunk/lib/Sema/SemaDecl.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=155293&r1=155292&r2=155293&view=diff > > ============================================================================== > --- cfe/trunk/lib/Sema/SemaDecl.cpp (original) > +++ cfe/trunk/lib/Sema/SemaDecl.cpp Sat Apr 21 13:42:51 2012 > @@ -9784,21 +9784,6 @@ > if (!Completed) > Record->completeDefinition(); > > - // Now that the record is complete, do any delayed exception spec > checks > - // we were missing. > - while (!DelayedDestructorExceptionSpecChecks.empty()) { > - const CXXDestructorDecl *Dtor = > - DelayedDestructorExceptionSpecChecks.back().first; > - if (Dtor->getParent() != Record) > - break; > - > - assert(!Dtor->getParent()->isDependentType() && > - "Should not ever add destructors of templates into the list."); > - CheckOverridingFunctionExceptionSpec(Dtor, > - DelayedDestructorExceptionSpecChecks.back().second); > - DelayedDestructorExceptionSpecChecks.pop_back(); > - } > - > } else { > ObjCIvarDecl **ClsFields = > reinterpret_cast<ObjCIvarDecl**>(RecFields.data()); > > Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=155293&r1=155292&r2=155293&view=diff > > ============================================================================== > --- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original) > +++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Sat Apr 21 13:42:51 2012 > @@ -7317,15 +7317,42 @@ > } > } > > +/// \brief Perform any semantic analysis which needs to be delayed until > all > +/// pending class member declarations have been parsed. > +void Sema::ActOnFinishCXXMemberDecls() { > + // Now we have parsed all exception specifications, determine the > implicit > + // exception specifications for destructors. > + for (unsigned i = 0, e = DelayedDestructorExceptionSpecs.size(); > + i != e; ++i) { > + CXXDestructorDecl *Dtor = DelayedDestructorExceptionSpecs[i]; > + AdjustDestructorExceptionSpec(Dtor->getParent(), Dtor, true); > + } > + DelayedDestructorExceptionSpecs.clear(); > + > + // Perform any deferred checking of exception specifications for virtual > + // destructors. > + for (unsigned i = 0, e = DelayedDestructorExceptionSpecChecks.size(); > + i != e; ++i) { > + const CXXDestructorDecl *Dtor = > + DelayedDestructorExceptionSpecChecks[i].first; > + assert(!Dtor->getParent()->isDependentType() && > + "Should not ever add destructors of templates into the list."); > + CheckOverridingFunctionExceptionSpec(Dtor, > + DelayedDestructorExceptionSpecChecks[i].second); > + } > + DelayedDestructorExceptionSpecChecks.clear(); > +} > + > void Sema::AdjustDestructorExceptionSpec(CXXRecordDecl *classDecl, > - CXXDestructorDecl *destructor) { > + CXXDestructorDecl *destructor, > + bool WasDelayed) { > // 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()) > + if (!WasDelayed && dtorType->hasExceptionSpec()) > return; > > ImplicitExceptionSpecification exceptSpec = > @@ -7342,6 +7369,14 @@ > > destructor->setType(ty); > > + // If we can't compute the exception specification for this destructor > yet > + // (because it depends on an exception specification which we have not > parsed > + // yet), make a note that we need to try again when the class is > complete. > + if (epi.ExceptionSpecType == EST_Delayed) { > + assert(!WasDelayed && "couldn't compute destructor exception spec"); > + DelayedDestructorExceptionSpecs.push_back(destructor); > + } > + > // 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. > > Modified: cfe/trunk/test/SemaCXX/implicit-exception-spec.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/implicit-exception-spec.cpp?rev=155293&r1=155292&r2=155293&view=diff > > ============================================================================== > --- cfe/trunk/test/SemaCXX/implicit-exception-spec.cpp (original) > +++ cfe/trunk/test/SemaCXX/implicit-exception-spec.cpp Sat Apr 21 13:42:51 > 2012 > @@ -54,3 +54,33 @@ > } t; // expected-note {{has no default constructor}} > }; > } > + > +namespace ImplicitDtorExceptionSpec { > + struct A { > + virtual ~A(); > + > + struct Inner { > + ~Inner() throw(); > + }; > + Inner inner; > + }; > + > + struct B { > + virtual ~B() {} // expected-note {{here}} > + }; > + > + struct C : B { > + virtual ~C() {} > + A a; > + }; > + > + struct D : B { > + ~D(); // expected-error {{more lax than base}} > + struct E { > + ~E(); > + struct F { > + ~F() throw(A); > + } f; > + } e; > + }; > +} > > > _______________________________________________ > cfe-commits mailing list > cfe-commits@cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits >
_______________________________________________ cfe-commits mailing list cfe-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits