blob: f3a070a01f74ca4c9e239ec7595a4590a4bf13a5 [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 {
20 bool b = noexcept(ConstExpr()) && ThrowSomething(); // expected-error {{exception specification is not available until end of class definition}}
21 };
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 {
28 int n = ExceptionIf<noexcept(TemplateArg())>::f(); // expected-error {{exception specification is not available until end of class definition}}
29 };
30 bool x = noexcept(TemplateArg());
31
32 // And within a nested class.
33 struct Nested {
34 struct Inner {
35 int n = ExceptionIf<noexcept(Nested())>::f(); // expected-error {{exception specification is not available until end of class definition}}
36 } inner;
37 };
38 bool y = noexcept(Nested());
39 bool z = noexcept(Nested::Inner());
40}
41
Richard Smith7a614d82011-06-11 17:19:42 +000042namespace ExceptionSpecification {
Douglas Gregor74e2fc32012-04-16 18:27:27 +000043 struct Nested {
Richard Smith7a614d82011-06-11 17:19:42 +000044 struct T {
Douglas Gregor74e2fc32012-04-16 18:27:27 +000045 T() noexcept(!noexcept(Nested())); // expected-error{{exception specification is not available until end of class definition}}
Richard Smith7a614d82011-06-11 17:19:42 +000046 } t;
47 };
48}
49
Richard Smith7a614d82011-06-11 17:19:42 +000050namespace DefaultArgument {
Richard Smith6c4c36c2012-03-30 20:53:28 +000051 struct Default {
Richard Smith7a614d82011-06-11 17:19:42 +000052 struct T {
Douglas Gregore4e68d42012-02-15 19:33:52 +000053 T(int = ExceptionIf<noexcept(Default())::f()); // expected-error {{call to implicitly-deleted default constructor}}
Richard Smith6c4c36c2012-03-30 20:53:28 +000054 } t; // expected-note {{has no default constructor}}
Richard Smith7a614d82011-06-11 17:19:42 +000055 };
56}
Richard Smitha4156b82012-04-21 18:42:51 +000057
58namespace ImplicitDtorExceptionSpec {
59 struct A {
60 virtual ~A();
61
62 struct Inner {
63 ~Inner() throw();
64 };
65 Inner inner;
66 };
67
68 struct B {
69 virtual ~B() {} // expected-note {{here}}
70 };
71
72 struct C : B {
73 virtual ~C() {}
74 A a;
75 };
76
77 struct D : B {
78 ~D(); // expected-error {{more lax than base}}
79 struct E {
80 ~E();
81 struct F {
82 ~F() throw(A);
83 } f;
84 } e;
85 };
86}