blob: b29cff5c5d12bd7b47388558df12f6e49f369e84 [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 Smithb9d0b762012-07-27 04:22:15 +000033 // FIXME: The diagnostic location is terrible here.
Richard Smith7a614d82011-06-11 17:19:42 +000034 struct Nested {
35 struct Inner {
Richard Smithb9d0b762012-07-27 04:22:15 +000036 int n = ExceptionIf<noexcept(Nested())>::f();
37 } inner; // expected-error {{cannot be used by non-static data member initializer}}
Richard Smith7a614d82011-06-11 17:19:42 +000038 };
39 bool y = noexcept(Nested());
40 bool z = noexcept(Nested::Inner());
Richard Smithb9d0b762012-07-27 04:22:15 +000041
42 struct Nested2 {
43 struct Inner;
44 int n = Inner().n; // expected-error {{cannot be used by non-static data member initializer}}
45 struct Inner {
46 int n = ExceptionIf<noexcept(Nested())>::f();
47 } inner;
48 };
Richard Smith7a614d82011-06-11 17:19:42 +000049}
50
Richard Smith7a614d82011-06-11 17:19:42 +000051namespace ExceptionSpecification {
Richard Smith6deb8202012-05-02 01:29:43 +000052 // A type is permitted to be used in a dynamic exception specification when it
53 // is still being defined, but isn't complete within such an exception
54 // specification.
55 struct Nested { // expected-note {{not complete}}
Richard Smith7a614d82011-06-11 17:19:42 +000056 struct T {
Richard Smith6deb8202012-05-02 01:29:43 +000057 T() noexcept(!noexcept(Nested())); // expected-error{{incomplete type}}
Richard Smith7a614d82011-06-11 17:19:42 +000058 } t;
59 };
60}
61
Richard Smith7a614d82011-06-11 17:19:42 +000062namespace DefaultArgument {
Richard Smith6c4c36c2012-03-30 20:53:28 +000063 struct Default {
Richard Smith7a614d82011-06-11 17:19:42 +000064 struct T {
Douglas Gregore4e68d42012-02-15 19:33:52 +000065 T(int = ExceptionIf<noexcept(Default())::f()); // expected-error {{call to implicitly-deleted default constructor}}
Richard Smith6c4c36c2012-03-30 20:53:28 +000066 } t; // expected-note {{has no default constructor}}
Richard Smith7a614d82011-06-11 17:19:42 +000067 };
68}
Richard Smitha4156b82012-04-21 18:42:51 +000069
70namespace ImplicitDtorExceptionSpec {
71 struct A {
72 virtual ~A();
73
74 struct Inner {
75 ~Inner() throw();
76 };
77 Inner inner;
78 };
79
80 struct B {
81 virtual ~B() {} // expected-note {{here}}
82 };
83
84 struct C : B {
85 virtual ~C() {}
86 A a;
87 };
88
89 struct D : B {
90 ~D(); // expected-error {{more lax than base}}
91 struct E {
92 ~E();
93 struct F {
94 ~F() throw(A);
95 } f;
96 } e;
97 };
98}