Home | History | Annotate | Download | only in SemaCXX
      1 // RUN: %clang_cc1 -fsyntax-only -fcxx-exceptions -verify -std=c++11 -Wall -Wno-unused-local-typedefs %s
      2 
      3 template<bool b> struct ExceptionIf { static int f(); };
      4 template<> struct ExceptionIf<false> { typedef int f; };
      5 
      6 // The exception specification of a defaulted default constructor depends on
      7 // the contents of in-class member initializers. However, the in-class member
      8 // initializers can depend on the exception specification of the constructor,
      9 // since the class is considered complete within them. We reject any such cases.
     10 namespace InClassInitializers {
     11   // Noexcept::Noexcept() is implicitly declared as noexcept(false), because it
     12   // directly invokes ThrowSomething(). However...
     13   //
     14   // If noexcept(Noexcept()) is false, then Noexcept() is a constant expression,
     15   // so noexcept(Noexcept()) is true. But if noexcept(Noexcept()) is true, then
     16   // Noexcept::Noexcept is not declared constexpr, therefore noexcept(Noexcept())
     17   // is false.
     18   bool ThrowSomething() noexcept(false);
     19   struct ConstExpr {
     20     bool b = noexcept(ConstExpr()) && ThrowSomething(); // expected-error {{cannot use defaulted default constructor of 'ConstExpr' within the class outside of member functions}}
     21   // expected-note@-1 {{implicit default constructor for 'InClassInitializers::ConstExpr' first required here}}
     22   };
     23 
     24   // Much more obviously broken: we can't parse the initializer without already
     25   // knowing whether it produces a noexcept expression.
     26   struct TemplateArg {
     27     int n = ExceptionIf<noexcept(TemplateArg())>::f(); // expected-error {{cannot use defaulted default constructor of 'TemplateArg' within the class outside of member functions}}
     28     // expected-note@-1 {{implicit default constructor for 'InClassInitializers::TemplateArg' first required here}}
     29   };
     30 
     31   // And within a nested class.
     32   struct Nested { // expected-note {{implicit default constructor for 'InClassInitializers::Nested::Inner' first required here}}
     33     struct Inner {
     34       // expected-error@+1 {{cannot use defaulted default constructor of 'Inner' within 'Nested' outside of member functions}}
     35       int n = ExceptionIf<noexcept(Nested())>::f(); // expected-note {{implicit default constructor for 'InClassInitializers::Nested' first required here}}
     36     } inner;
     37   };
     38 
     39   struct Nested2 { // expected-error {{implicit default constructor for 'InClassInitializers::Nested2' must explicitly initialize the member 'inner' which does not have a default constructor}}
     40     struct Inner;
     41     int n = Inner().n; // expected-note {{implicit default constructor for 'InClassInitializers::Nested2::Inner' first required here}}
     42     struct Inner { // expected-note {{declared here}}
     43       // expected-error@+1 {{cannot use defaulted default constructor of 'Inner' within 'Nested2' outside of member functions}}
     44       int n = ExceptionIf<noexcept(Nested2())>::f();
     45       // expected-note@-1 {{implicit default constructor for 'InClassInitializers::Nested2' first required here}}
     46     } inner; // expected-note {{member is declared here}}
     47   };
     48 }
     49 
     50 namespace ExceptionSpecification {
     51   // FIXME: This diagnostic is quite useless; we should indicate whose
     52   // exception specification we were looking for and why.
     53   struct Nested {
     54     struct T {
     55       T() noexcept(!noexcept(Nested()));
     56     } t; // expected-error{{exception specification is not available until end of class definition}}
     57   };
     58 }
     59 
     60 namespace DefaultArgument {
     61   struct Default {
     62     struct T {
     63       T(int = ExceptionIf<noexcept(Default())::f()); // expected-error {{call to implicitly-deleted default constructor}}
     64     } t; // expected-note {{has no default constructor}}
     65   };
     66 }
     67 
     68 namespace ImplicitDtorExceptionSpec {
     69   struct A {
     70     virtual ~A();
     71 
     72     struct Inner {
     73       ~Inner() throw();
     74     };
     75     Inner inner;
     76   };
     77 
     78   struct B {
     79     virtual ~B() {} // expected-note {{here}}
     80   };
     81 
     82   struct C : B {
     83     virtual ~C() {}
     84     A a;
     85   };
     86 
     87   struct D : B {
     88     ~D(); // expected-error {{more lax than base}}
     89     struct E {
     90       ~E();
     91       struct F {
     92         ~F() throw(A);
     93       } f;
     94     } e;
     95   };
     96 }
     97