On 1/26/26 11:16 PM, Jakub Jelinek wrote:
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.
OK.
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