aboutsummaryrefslogtreecommitdiff
path: root/gcc/testsuite/g++.dg/cpp23/constexpr-nonlit11.C
blob: e08809f873cfde101809b7873154ee08a9ee70d3 (plain)
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
// PR c++/106649
// P2448 - Relaxing some constexpr restrictions
// { dg-do compile { target c++23 } }
// { dg-options "-Winvalid-constexpr -pedantic-errors" }

// [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 { ! implicit_constexpr } } }
  S(int, int) { }
  // Target constructor isn't constexpr.
  constexpr S() : S(42, 42) { } // { dg-warning "call to" "" { target { ! implicit_constexpr } } }
};

namespace N1 {
struct X {
  void x();
};
struct Y {
  X x;
  constexpr void y() { x.x(); } // { dg-warning "call to" }
};
}

void g();

struct A {
  constexpr A() { g(); } // { dg-warning "call to" }
};

struct B {
  constexpr B& operator=(const B&) { g(); return *this; } // { dg-warning "call to" }
  constexpr B& operator=(B&&) { g(); return *this; } // { dg-warning "call to" }
};