On Sat, Jan 24, 2026 at 07:09:44PM +0800, Jason Merrill wrote: > > Though, if we request a CWG to change this (shall I do that or will you?), > > we > > need to also change the immediate_escalating_function_p function and add > > test coverage for that (though guess that is desirable anyway even if it is > > not immediate-escalating to test that we error on that). > > I will.
Ok, here is an incremental patch on top of the previously posted one which implements your core issue. 2026-01-26 Jakub Jelinek <[email protected]> * cp-gimplify.cc (immediate_escalating_function_p): Implement CWG3153 - Immediate-escalating defaulted comparison. Don't check special_memfn_p for sfk_none for DECL_DEFAULTED_FNs. * decl.cc (grokfndecl): Similarly for initialized == SD_DEFAULTED fns. * g++.dg/reflect/cwg3153.C: New test. --- gcc/cp/cp-gimplify.cc.jj 2026-01-26 12:37:18.693329597 +0100 +++ gcc/cp/cp-gimplify.cc 2026-01-26 14:55:23.965421305 +0100 @@ -502,10 +502,9 @@ immediate_escalating_function_p (tree fn specifier */ if (LAMBDA_FUNCTION_P (fn)) return true; - /* -- a defaulted special member function that is not declared with the + /* -- a defaulted function that is not declared with the consteval specifier */ - special_function_kind sfk = special_memfn_p (fn); - if (sfk != sfk_none && DECL_DEFAULTED_FN (fn)) + if (DECL_DEFAULTED_FN (fn)) return true; /* -- a function that results from the instantiation of a templated entity defined with the constexpr specifier. */ --- gcc/cp/decl.cc.jj 2026-01-26 14:54:39.183183807 +0100 +++ gcc/cp/decl.cc 2026-01-26 14:56:01.841776389 +0100 @@ -12679,10 +12679,10 @@ grokfndecl (tree ctype, if (DECL_CONSTRUCTOR_P (decl) && !grok_ctor_properties (ctype, decl)) return NULL_TREE; - /* Don't call check_consteval_only_fn for defaulted special member - functions. Those are immediate-escalating functions but at this point - DECL_DEFAULTED_P has not been set. */ - if (initialized != SD_DEFAULTED || special_memfn_p (decl) == sfk_none) + /* Don't call check_consteval_only_fn for defaulted functions. Those are + immediate-escalating functions but at this point DECL_DEFAULTED_P has + not been set. */ + if (initialized != SD_DEFAULTED) check_consteval_only_fn (decl); if (ctype == NULL_TREE || check) --- gcc/testsuite/g++.dg/reflect/cwg3153.C.jj 2026-01-26 15:51:29.872113827 +0100 +++ gcc/testsuite/g++.dg/reflect/cwg3153.C 2026-01-26 16:08:27.287792511 +0100 @@ -0,0 +1,51 @@ +// CWG3153 +// { dg-do compile { target c++26 } } +// { dg-additional-options "-freflection" } + +#include <compare> + +struct A { + decltype (^^::) a = ^^::; + consteval A () {} + bool operator== (const A &) const = default; // { dg-bogus "function of consteval-only type must be declared 'consteval'" } +}; + +template <typename T, T V> +struct B +{ + T b = V; + consteval B () {} + bool operator== (const B &) const = default; +}; + +struct C { + decltype (^^::) c= ^^::; + int d = 0; + consteval C () {} + consteval bool operator== (const C &x) const { return d == x.d; } + consteval auto operator<=> (const C &x) const { return d <=> x.d; } +}; + +struct D : public C { + int e = 0; + consteval D () {} + auto operator<=> (const D &) const = default; +}; + +consteval +{ + A a; + A b; + if (a != b) throw 1; + B <decltype (^^::), ^^::> c; + B <decltype (^^::), ^^::> d; + if (c != d) throw 2; + D e; + D f; + if (e != f) throw 3; + f.d = 2; + if (e >= f) throw 4; + f.d = 0; + f.e = -1; + if (e <= f) throw 5; +} Jakub
