128 lines · cpp
1// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++112 3// Implicitly-defined default constructors are constexpr if the implicit4// definition would be.5struct NonConstexpr1 { // expected-note {{here}}6 int a;7};8struct NonConstexpr2 { // expected-note {{here}}9 NonConstexpr1 nl;10};11struct NonConstexpr2a : NonConstexpr1 { };12constexpr NonConstexpr1 nc1 = NonConstexpr1(); // ok, does not call constructor13constexpr NonConstexpr2 nc2 = NonConstexpr2(); // ok, does not call constructor14constexpr NonConstexpr2a nc2a = NonConstexpr2a(); // ok, does not call constructor15constexpr int nc2_a = NonConstexpr2().nl.a; // ok16constexpr int nc2a_a = NonConstexpr2a().a; // ok17struct 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 22struct Constexpr1 {};23constexpr Constexpr1 c1 = Constexpr1(); // ok24struct NonConstexpr3 : virtual Constexpr1 {}; // expected-note {{struct with virtual base}} expected-note {{declared here}}25constexpr NonConstexpr3 nc3 = NonConstexpr3(); // expected-error {{non-literal type 'const NonConstexpr3'}}26 27struct Constexpr2 {28 int a = 0;29};30constexpr Constexpr2 c2 = Constexpr2(); // ok31 32int n;33struct Member {34 Member() : a(n) {}35 constexpr Member(int&a) : a(a) {}36 int &a;37};38struct NonConstexpr4 { // expected-note {{here}}39 Member m;40};41constexpr NonConstexpr4 nc4 = NonConstexpr4(); // expected-error {{constant expression}} expected-note {{non-constexpr constructor 'NonConstexpr4'}}42struct Constexpr3 {43 constexpr Constexpr3() : m(n) {}44 Member m;45};46constexpr Constexpr3 c3 = Constexpr3(); // ok47struct Constexpr4 {48 Constexpr3 m;49};50constexpr Constexpr4 c4 = Constexpr4(); // ok51 52 53// This rule breaks some legal C++98 programs!54struct A {}; // expected-note {{here}}55struct B {56 friend A::A(); // expected-error {{non-constexpr declaration of 'A' follows constexpr declaration}}57};58 59namespace 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 98namespace PR48763 {99 // FIXME: We implement a speculative wording fix here: if a class inherits a100 // default constructor and doesn't declare one itself, we declare an default101 // constructor implicitly. This allows us to meanignfully reason about102 // whether that default constructor is constexpr, trivial, and so on.103 struct A { constexpr A() {} };104 struct B : A {105 using A::A;106 constexpr B(int) {}107 };108 struct C { B b; };109 constexpr C c;110 111 struct D { int n; };112 struct E : D { using D::D; E(int); };113 static_assert(E().n == 0, "");114 static_assert(E{}.n == 0, "");115 116 struct F { E e; };117 static_assert(F().e.n == 0, "");118 static_assert(F{}.e.n == 0, "");119 120 union U { E e; };121 U u; // OK, trivial default constructor122 123 struct G { G(); };124 struct H : D { using D::D; H(int); G g; };125 union V { H h; }; // expected-note {{field 'h' has a non-trivial default constructor}}126 V v; // expected-error {{deleted}}127}128