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