https://gcc.gnu.org/g:9b7b6a4075cccfb7480a3a642ccdcb183625a2af

commit r16-7061-g9b7b6a4075cccfb7480a3a642ccdcb183625a2af
Author: Jakub Jelinek <[email protected]>
Date:   Tue Jan 27 10:24:49 2026 +0100

    c++: Implement CWG3153 - Immediate-escalating defaulted comparison
    
    The following patch implements the
    https://cplusplus.github.io/CWG/issues/3153.html
    core issue proposal.
    
    2026-01-27  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.

Diff:
---
 gcc/cp/cp-gimplify.cc                  |  5 ++--
 gcc/cp/decl.cc                         |  8 +++---
 gcc/testsuite/g++.dg/reflect/cwg3153.C | 51 ++++++++++++++++++++++++++++++++++
 3 files changed, 57 insertions(+), 7 deletions(-)

diff --git a/gcc/cp/cp-gimplify.cc b/gcc/cp/cp-gimplify.cc
index 30d6a07e376d..59e01c103fd4 100644
--- a/gcc/cp/cp-gimplify.cc
+++ b/gcc/cp/cp-gimplify.cc
@@ -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.  */
diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
index 3bbc28c913d8..40a95eb15288 100644
--- a/gcc/cp/decl.cc
+++ b/gcc/cp/decl.cc
@@ -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)
diff --git a/gcc/testsuite/g++.dg/reflect/cwg3153.C 
b/gcc/testsuite/g++.dg/reflect/cwg3153.C
new file mode 100644
index 000000000000..5f2b1fd665ff
--- /dev/null
+++ b/gcc/testsuite/g++.dg/reflect/cwg3153.C
@@ -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;
+}

Reply via email to