1// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
2
3// If the implicitly-defined constructor would satisfy the requirements of a
4// constexpr constructor, the implicitly-defined constructor is constexpr.
5struct Constexpr1 {
6  constexpr Constexpr1() : n(0) {}
7  int n;
8};
9constexpr Constexpr1 c1a = Constexpr1(Constexpr1()); // ok
10constexpr Constexpr1 c1b = Constexpr1(Constexpr1(c1a)); // ok
11
12struct Constexpr2 {
13  Constexpr1 ce1;
14  constexpr Constexpr2() = default;
15  constexpr Constexpr2(const Constexpr2 &o) : ce1(o.ce1) {}
16  // no move constructor
17};
18
19constexpr Constexpr2 c2a = Constexpr2(Constexpr2()); // ok
20constexpr Constexpr2 c2b = Constexpr2(Constexpr2(c2a)); // ok
21
22struct Constexpr3 {
23  Constexpr2 ce2;
24  // all special constructors are constexpr, move ctor calls ce2's copy ctor
25};
26
27constexpr Constexpr3 c3a = Constexpr3(Constexpr3()); // ok
28constexpr Constexpr3 c3b = Constexpr3(Constexpr3(c3a)); // ok
29
30struct NonConstexprCopy {
31  constexpr NonConstexprCopy() = default;
32  NonConstexprCopy(const NonConstexprCopy &);
33  constexpr NonConstexprCopy(NonConstexprCopy &&) = default;
34
35  int n = 42;
36};
37
38NonConstexprCopy::NonConstexprCopy(const NonConstexprCopy &) = default; // expected-note {{here}}
39
40constexpr NonConstexprCopy ncc1 = NonConstexprCopy(NonConstexprCopy()); // ok
41constexpr NonConstexprCopy ncc2 = ncc1; // expected-error {{constant expression}} expected-note {{non-constexpr constructor}}
42
43struct NonConstexprDefault {
44  NonConstexprDefault() = default;
45  constexpr NonConstexprDefault(int n) : n(n) {}
46  int n;
47};
48struct Constexpr4 {
49  NonConstexprDefault ncd;
50};
51
52constexpr NonConstexprDefault ncd = NonConstexprDefault(NonConstexprDefault(1));
53constexpr Constexpr4 c4a = { ncd };
54constexpr Constexpr4 c4b = Constexpr4(c4a);
55constexpr Constexpr4 c4c = Constexpr4(static_cast<Constexpr4&&>(const_cast<Constexpr4&>(c4b)));
56
57struct Constexpr5Base {};
58struct Constexpr5 : Constexpr5Base { constexpr Constexpr5() {} };
59constexpr Constexpr5 ce5move = Constexpr5();
60constexpr Constexpr5 ce5copy = ce5move;
61
62// An explicitly-defaulted constructor doesn't become constexpr until the end of
63// its class. Make sure we note that the class has a constexpr constructor when
64// that happens.
65namespace PR13052 {
66  template<typename T> struct S {
67    S() = default; // expected-note 2{{here}}
68    S(S&&) = default;
69    S(const S&) = default;
70    T t;
71  };
72
73  struct U {
74    U() = default;
75    U(U&&) = default;
76    U(const U&) = default;
77  };
78
79  struct V {
80    V(); // expected-note {{here}}
81    V(V&&) = default;
82    V(const V&) = default;
83  };
84
85  struct W {
86    W(); // expected-note {{here}}
87  };
88
89  static_assert(__is_literal_type(U), "");
90  static_assert(!__is_literal_type(V), "");
91  static_assert(!__is_literal_type(W), "");
92  static_assert(__is_literal_type(S<U>), "");
93  static_assert(!__is_literal_type(S<V>), "");
94  static_assert(!__is_literal_type(S<W>), "");
95
96  struct X {
97    friend constexpr U::U() noexcept;
98    friend constexpr U::U(U&&) noexcept;
99    friend constexpr U::U(const U&) noexcept;
100    friend constexpr V::V(); // expected-error {{follows non-constexpr declaration}}
101    friend constexpr V::V(V&&) noexcept;
102    friend constexpr V::V(const V&) noexcept;
103    friend constexpr W::W(); // expected-error {{follows non-constexpr declaration}}
104    friend constexpr W::W(W&&) noexcept;
105    friend constexpr W::W(const W&) noexcept;
106    friend constexpr S<U>::S() noexcept;
107    friend constexpr S<U>::S(S<U>&&) noexcept;
108    friend constexpr S<U>::S(const S<U>&) noexcept;
109    friend constexpr S<V>::S(); // expected-error {{follows non-constexpr declaration}}
110    friend constexpr S<V>::S(S<V>&&) noexcept;
111    friend constexpr S<V>::S(const S<V>&) noexcept;
112    friend constexpr S<W>::S(); // expected-error {{follows non-constexpr declaration}}
113    friend constexpr S<W>::S(S<W>&&) noexcept;
114    friend constexpr S<W>::S(const S<W>&) noexcept;
115  };
116}
117
118namespace Mutable {
119  struct A {
120    constexpr A(A &);
121    A(const A &);
122  };
123  struct B {
124    constexpr B(const B &) = default; // ok
125    mutable A a;
126  };
127  struct C {
128    constexpr C(const C &) = default; // expected-error {{not constexpr}}
129    A a;
130  };
131}
132