blob: 228e90f14c1b1cc81d59b166c92e93dfd0bb3499 [file] [log] [blame]
// PR c++/106649
// P2448 - Relaxing some constexpr restrictions
// { dg-do compile { target c++14 } }
// { dg-options "" }
// [dcl.constexpr]/4 used to say:
// The definition of a constexpr constructor whose function-body
// is not = delete shall additionally satisfy the following requirements:
// (4.1) for a non-delegating constructor, every constructor selected to initialize non-static data members and base class subobjects shall be a constexpr constructor;
// (4.2) for a delegating constructor, the target constructor shall be a constexpr constructor.
// This continues to be OK.
struct Length {
constexpr explicit Length(int i = 0) : val(i) { }
private:
int val;
};
struct X {
X() {}
X(int i_) : i(i_) {}
int i;
};
struct S {
X x;
// Calls a non-constexpr constructor X::X(int).
constexpr S(int i) : x(i) { } // { dg-warning "call to" "" { target c++20_down } }
S(int, int) { }
// Target constructor isn't constexpr.
constexpr S() : S(42, 42) { } // { dg-warning "call to" "" { target c++20_down } }
};
namespace N1 {
struct X {
void x();
};
struct Y {
X x;
constexpr void y() { x.x(); } // { dg-warning "call to" "" { target c++20_down } }
};
}
void g();
struct A {
constexpr A() { g(); } // { dg-warning "call to" "" { target c++20_down } }
};
struct B {
constexpr B& operator=(const B&) { g(); return *this; } // { dg-warning "call to" "" { target c++20_down } }
constexpr B& operator=(B&&) { g(); return *this; } // { dg-warning "call to" "" { target c++20_down } }
};