132 lines
4.1 KiB
C++
132 lines
4.1 KiB
C++
|
// 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;
|
||
|
};
|
||
|
}
|