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


Reply via email to