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