1 | // RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11 |
2 | |
3 | // Implicitly-defined default constructors are constexpr if the implicit |
4 | // definition would be. |
5 | struct NonConstexpr1 { // expected-note {{here}} |
6 | int a; |
7 | }; |
8 | struct NonConstexpr2 { // expected-note {{here}} |
9 | NonConstexpr1 nl; |
10 | }; |
11 | struct NonConstexpr2a : NonConstexpr1 { }; |
12 | constexpr NonConstexpr1 nc1 = NonConstexpr1(); // ok, does not call constructor |
13 | constexpr NonConstexpr2 nc2 = NonConstexpr2(); // ok, does not call constructor |
14 | constexpr NonConstexpr2a nc2a = NonConstexpr2a(); // ok, does not call constructor |
15 | constexpr int nc2_a = NonConstexpr2().nl.a; // ok |
16 | constexpr int nc2a_a = NonConstexpr2a().a; // ok |
17 | struct Helper { |
18 | friend constexpr NonConstexpr1::NonConstexpr1(); // expected-error {{follows non-constexpr declaration}} |
19 | friend constexpr NonConstexpr2::NonConstexpr2(); // expected-error {{follows non-constexpr declaration}} |
20 | }; |
21 | |
22 | struct Constexpr1 {}; |
23 | constexpr Constexpr1 c1 = Constexpr1(); // ok |
24 | struct NonConstexpr3 : virtual Constexpr1 {}; // expected-note {{struct with virtual base}} expected-note {{declared here}} |
25 | constexpr NonConstexpr3 nc3 = NonConstexpr3(); // expected-error {{non-literal type 'const NonConstexpr3'}} |
26 | |
27 | struct Constexpr2 { |
28 | int a = 0; |
29 | }; |
30 | constexpr Constexpr2 c2 = Constexpr2(); // ok |
31 | |
32 | int n; |
33 | struct Member { |
34 | Member() : a(n) {} |
35 | constexpr Member(int&a) : a(a) {} |
36 | int &a; |
37 | }; |
38 | struct NonConstexpr4 { // expected-note {{here}} |
39 | Member m; |
40 | }; |
41 | constexpr NonConstexpr4 nc4 = NonConstexpr4(); // expected-error {{constant expression}} expected-note {{non-constexpr constructor 'NonConstexpr4'}} |
42 | struct Constexpr3 { |
43 | constexpr Constexpr3() : m(n) {} |
44 | Member m; |
45 | }; |
46 | constexpr Constexpr3 c3 = Constexpr3(); // ok |
47 | struct Constexpr4 { |
48 | Constexpr3 m; |
49 | }; |
50 | constexpr Constexpr4 c4 = Constexpr4(); // ok |
51 | |
52 | |
53 | // This rule breaks some legal C++98 programs! |
54 | struct A {}; // expected-note {{here}} |
55 | struct B { |
56 | friend A::A(); // expected-error {{non-constexpr declaration of 'A' follows constexpr declaration}} |
57 | }; |
58 | |
59 | namespace UnionCtors { |
60 | union A { // expected-note {{here}} |
61 | int a; |
62 | int b; |
63 | }; |
64 | union B { |
65 | int a; |
66 | int b = 5; |
67 | }; |
68 | union C { |
69 | int a = 5; |
70 | int b; |
71 | }; |
72 | struct D { |
73 | union { |
74 | int a = 5; |
75 | int b; |
76 | }; |
77 | union { |
78 | int c; |
79 | int d = 5; |
80 | }; |
81 | }; |
82 | struct E { // expected-note {{here}} |
83 | union { |
84 | int a; |
85 | int b; |
86 | }; |
87 | }; |
88 | |
89 | struct Test { |
90 | friend constexpr A::A() noexcept; // expected-error {{follows non-constexpr declaration}} |
91 | friend constexpr B::B() noexcept; |
92 | friend constexpr C::C() noexcept; |
93 | friend constexpr D::D() noexcept; |
94 | friend constexpr E::E() noexcept; // expected-error {{follows non-constexpr declaration}} |
95 | }; |
96 | } |
97 | |