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 {
MemberMember34   Member() : a(n) {}
MemberMember35   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 {
Constexpr3Constexpr343   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