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.
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 constructor
13constexpr NonConstexpr2 nc2 = NonConstexpr2(); // ok, does not call constructor
14constexpr NonConstexpr2a nc2a = NonConstexpr2a(); // ok, does not call constructor
15constexpr int nc2_a = NonConstexpr2().nl.a; // ok
16constexpr int nc2a_a = NonConstexpr2a().a; // ok
17struct 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(); // ok
24struct 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(); // ok
31
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(); // ok
47struct Constexpr4 {
48  Constexpr3 m;
49};
50constexpr Constexpr4 c4 = Constexpr4(); // ok
51
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