[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

Douglas Gregor dgregor at apple.com
Mon Apr 23 09:26:18 PDT 2012


On Apr 21, 2012, at 7:17 PM, Richard Smith <richard at metafoo.co.uk> wrote:

> This and r155289 would make good candidates for porting to the branch.

Both approved.

> 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/20120423/88049424/attachment.html>


More information about the cfe-commits mailing list