On Sat, Jan 17, 2026 at 02:09:57PM +0100, Jakub Jelinek wrote:
> And another testcase I have no idea what actually should happen is
> struct Q;
> constexpr Q *q = nullptr;
> struct Q { decltype (^^int) x = ^^int; };
> I think Q * is not a consteval-only type when parsing the q declaration,
> but when the Q class is defined, it is consteval-only and so is Q *.
> So, shall we somehow later on arrange for q not to be emitted (or error
> if say something non-consteval made it odr-used? Though, if what is
> consteval-only can change at any point, that is kind of complicated.
Actually, that means we can't cache consteval-only on types at all.
struct A;
struct B { A *p; constexpr B (A *x) : p (x) {} };
template <typename T>
void use (T &) {}
constexpr B c1 = nullptr;
use (c1); // Is this an error or not? c1 at its definition doesn't have
// consteval-only type, but at the end of TU it does
template <typename T, int N>
constexpr T *foo (T *x) { return x; }
constexpr B *c2 = foo <B, 42> (nullptr);
// Is foo <B, 42> immediate-only or not?
struct A { decltype (^^::) a = ^^::; };
constexpr B c3 = nullptr;
constexpr B *c4 = foo <B, 43> (nullptr);
// foo <B, 43> should be immediate-only.
Whether a type is consteval-only can change at any time during the parsing,
but then I'm wondering whether the standard shouldn't talk about
consteval-only types at point P or something similar most of the time.
Jakub