blob: 559c3013f7e94be310168e674cfb22b8d00b5c91 [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
42// FIXME:
43// The same problem arises in delayed parsing of exception specifications,
44// which clang does not yet support.
45namespace ExceptionSpecification {
46 struct Nested { // expected-note {{not complete}}
47 struct T {
48 T() noexcept(!noexcept(Nested())); // expected-error {{incomplete type}}
49 } t;
50 };
51}
52
53// FIXME:
54// The same problem arises in delayed parsing of default arguments,
55// which clang does not yet support.
56namespace DefaultArgument {
57 // FIXME: this diagnostic is completely wrong.
58 struct Default { // expected-note {{explicitly marked deleted here}}
59 struct T {
60 T(int = ExceptionIf<noexcept(Default())::f()); // expected-error {{call to deleted constructor}}
61 } t;
62 };
63}