[cfe-commits] r155293 - in /cfe/trunk: include/clang/Sema/Sema.h lib/Parse/ParseDeclCXX.cpp lib/Sema/SemaDecl.cpp lib/Sema/SemaDeclCXX.cpp test/SemaCXX/implicit-exception-spec.cpp
Richard Smith
richard at metafoo.co.uk
Sat Apr 21 19:17:41 PDT 2012
This and r155289 would make good candidates for porting to the branch.
On Sat, Apr 21, 2012 at 11:42 AM, Richard Smith
<richard-llvm at 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 at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20120421/ad56cc1e/attachment.html>
More information about the cfe-commits
mailing list