| 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. |
| 5 | struct Constexpr1 { |
| 6 | constexpr Constexpr1() : n(0) {} |
| 7 | int n; |
| 8 | }; |
| 9 | constexpr Constexpr1 c1a = Constexpr1(Constexpr1()); // ok |
| 10 | constexpr Constexpr1 c1b = Constexpr1(Constexpr1(c1a)); // ok |
| 11 | |
| 12 | struct Constexpr2 { |
| 13 | Constexpr1 ce1; |
| 14 | constexpr Constexpr2() = default; |
| 15 | constexpr Constexpr2(const Constexpr2 &o) : ce1(o.ce1) {} |
| 16 | // no move constructor |
| 17 | }; |
| 18 | |
| 19 | constexpr Constexpr2 c2a = Constexpr2(Constexpr2()); // ok |
| 20 | constexpr Constexpr2 c2b = Constexpr2(Constexpr2(c2a)); // ok |
| 21 | |
| 22 | struct Constexpr3 { |
| 23 | Constexpr2 ce2; |
| 24 | // all special constructors are constexpr, move ctor calls ce2's copy ctor |
| 25 | }; |
| 26 | |
| 27 | constexpr Constexpr3 c3a = Constexpr3(Constexpr3()); // ok |
| 28 | constexpr Constexpr3 c3b = Constexpr3(Constexpr3(c3a)); // ok |
| 29 | |
| 30 | struct NonConstexprCopy { |
| 31 | constexpr NonConstexprCopy() = default; |
| 32 | NonConstexprCopy(const NonConstexprCopy &); |
| 33 | constexpr NonConstexprCopy(NonConstexprCopy &&) = default; |
| 34 | |
| 35 | int n = 42; |
| 36 | }; |
| 37 | |
| 38 | NonConstexprCopy::NonConstexprCopy(const NonConstexprCopy &) = default; // expected-note {{here}} |
| 39 | |
| 40 | constexpr NonConstexprCopy ncc1 = NonConstexprCopy(NonConstexprCopy()); // ok |
| 41 | constexpr NonConstexprCopy ncc2 = ncc1; // expected-error {{constant expression}} expected-note {{non-constexpr constructor}} |
| 42 | |
| 43 | struct NonConstexprDefault { |
| 44 | NonConstexprDefault() = default; |
| 45 | constexpr NonConstexprDefault(int n) : n(n) {} |
| 46 | int n; |
| 47 | }; |
| 48 | struct Constexpr4 { |
| 49 | NonConstexprDefault ncd; |
| 50 | }; |
| 51 | |
| 52 | constexpr NonConstexprDefault ncd = NonConstexprDefault(NonConstexprDefault(1)); |
| 53 | constexpr Constexpr4 c4a = { ncd }; |
| 54 | constexpr Constexpr4 c4b = Constexpr4(c4a); |
| 55 | constexpr Constexpr4 c4c = Constexpr4(static_cast<Constexpr4&&>(const_cast<Constexpr4&>(c4b))); |
| 56 | |
| 57 | struct Constexpr5Base {}; |
| 58 | struct Constexpr5 : Constexpr5Base { constexpr Constexpr5() {} }; |
| 59 | constexpr Constexpr5 ce5move = Constexpr5(); |
| 60 | constexpr 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. |
| 65 | namespace 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 | |
| 118 | namespace 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 | |