blob: e26f985f0d0ae0ea170f38ecfc6c04260e7d58e7 [file] [log] [blame]
Richard Smith762bb9d2011-10-13 22:29:44 +00001// RUN: %clang_cc1 -fsyntax-only -fcxx-exceptions -verify -std=c++11 -Wall %s
Richard Smith7a614d82011-06-11 17:19:42 +00002
3template<bool b> struct ExceptionIf { static int f(); };
4template<> 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.
10namespace 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 {
Richard Smithb9d0b762012-07-27 04:22:15 +000020 bool b = noexcept(ConstExpr()) && ThrowSomething(); // expected-error {{cannot be used by non-static data member initializer}}
Richard Smith7a614d82011-06-11 17:19:42 +000021 };
22 // We can use it now.
23 bool w = noexcept(ConstExpr());
24
25 // Much more obviously broken: we can't parse the initializer without already
26 // knowing whether it produces a noexcept expression.
27 struct TemplateArg {
Richard Smithb9d0b762012-07-27 04:22:15 +000028 int n = ExceptionIf<noexcept(TemplateArg())>::f(); // expected-error {{cannot be used by non-static data member initializer}}
Richard Smith7a614d82011-06-11 17:19:42 +000029 };
30 bool x = noexcept(TemplateArg());
31
32 // And within a nested class.
Richard Smithce2661f2012-11-07 01:14:25 +000033 struct Nested { // expected-error {{cannot be used by non-static data member initializer}}
Richard Smith7a614d82011-06-11 17:19:42 +000034 struct Inner {
Richard Smithce2661f2012-11-07 01:14:25 +000035 int n = ExceptionIf<noexcept(Nested())>::f(); // expected-note {{implicit default constructor for 'InClassInitializers::Nested' first required here}}
36 } inner;
Richard Smith7a614d82011-06-11 17:19:42 +000037 };
Richard Smithb9d0b762012-07-27 04:22:15 +000038
39 struct Nested2 {
40 struct Inner;
41 int n = Inner().n; // expected-error {{cannot be used by non-static data member initializer}}
42 struct Inner {
Richard Smithce2661f2012-11-07 01:14:25 +000043 int n = ExceptionIf<noexcept(Nested2())>::f();
Richard Smithb9d0b762012-07-27 04:22:15 +000044 } inner;
45 };
Richard Smith7a614d82011-06-11 17:19:42 +000046}
47
Richard Smith7a614d82011-06-11 17:19:42 +000048namespace ExceptionSpecification {
Richard Smith6deb8202012-05-02 01:29:43 +000049 // A type is permitted to be used in a dynamic exception specification when it
50 // is still being defined, but isn't complete within such an exception
51 // specification.
52 struct Nested { // expected-note {{not complete}}
Richard Smith7a614d82011-06-11 17:19:42 +000053 struct T {
Richard Smith6deb8202012-05-02 01:29:43 +000054 T() noexcept(!noexcept(Nested())); // expected-error{{incomplete type}}
Richard Smith7a614d82011-06-11 17:19:42 +000055 } t;
56 };
57}
58
Richard Smith7a614d82011-06-11 17:19:42 +000059namespace DefaultArgument {
Richard Smith6c4c36c2012-03-30 20:53:28 +000060 struct Default {
Richard Smith7a614d82011-06-11 17:19:42 +000061 struct T {
Douglas Gregore4e68d42012-02-15 19:33:52 +000062 T(int = ExceptionIf<noexcept(Default())::f()); // expected-error {{call to implicitly-deleted default constructor}}
Richard Smith6c4c36c2012-03-30 20:53:28 +000063 } t; // expected-note {{has no default constructor}}
Richard Smith7a614d82011-06-11 17:19:42 +000064 };
65}
Richard Smitha4156b82012-04-21 18:42:51 +000066
67namespace ImplicitDtorExceptionSpec {
68 struct A {
69 virtual ~A();
70
71 struct Inner {
72 ~Inner() throw();
73 };
74 Inner inner;
75 };
76
77 struct B {
78 virtual ~B() {} // expected-note {{here}}
79 };
80
81 struct C : B {
82 virtual ~C() {}
83 A a;
84 };
85
86 struct D : B {
87 ~D(); // expected-error {{more lax than base}}
88 struct E {
89 ~E();
90 struct F {
91 ~F() throw(A);
92 } f;
93 } e;
94 };
95}