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