| 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 | |