From ae37ade22ecf4e4ca2911d6628f8bec20c3d6422 Mon Sep 17 00:00:00 2001 From: Patrick Palka Date: Wed, 11 Feb 2026 21:35:35 -0500 Subject: [PATCH] c++: relax ref-qual overloading rules for C++20 [PR98939] As explained in one of Tomasz's library papers P2438R2[1], C++20 allows ref-qualified member overloads to coexist with non-ref-qualified ones, but at the time of writing no compiler supported that. This patch implements this C++20 relaxation so that we can in turn implement P2438R2 as originally intended -- without needing to change the signature of the main string::substr overload. [1]: https://wg21.link/P2438R2#_modifying_existing_const_overload PR c++/98939 PR libstdc++/119745 gcc/cp/ChangeLog: * class.cc (object_parms_correspond): Allow differing FUNCTION_REF_QUALIFIED in C++20. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/ref-qual5.C: Expect no diagnostics in C++20. Reviewed-by: Jason Merrill --- gcc/cp/class.cc | 7 ++++--- gcc/testsuite/g++.dg/cpp0x/ref-qual5.C | 7 ++++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/gcc/cp/class.cc b/gcc/cp/class.cc index 315ffd316ffb..a223f71dbbe9 100644 --- a/gcc/cp/class.cc +++ b/gcc/cp/class.cc @@ -1223,9 +1223,10 @@ object_parms_correspond (tree fn, tree method, tree context) && DECL_IOBJ_MEMBER_FUNCTION_P (method)) { /* Either both or neither need to be ref-qualified for - differing quals to allow overloading. */ - if ((FUNCTION_REF_QUALIFIED (fn_type) - == FUNCTION_REF_QUALIFIED (method_type)) + differing quals to allow overloading before C++20 (P1787R6). */ + if ((cxx_dialect >= cxx20 + || (FUNCTION_REF_QUALIFIED (fn_type) + == FUNCTION_REF_QUALIFIED (method_type))) && (type_memfn_quals (fn_type) != type_memfn_quals (method_type) || type_memfn_rqual (fn_type) != type_memfn_rqual (method_type))) return false; diff --git a/gcc/testsuite/g++.dg/cpp0x/ref-qual5.C b/gcc/testsuite/g++.dg/cpp0x/ref-qual5.C index e3d26e5a78fa..42e9bd3b4aee 100644 --- a/gcc/testsuite/g++.dg/cpp0x/ref-qual5.C +++ b/gcc/testsuite/g++.dg/cpp0x/ref-qual5.C @@ -1,5 +1,6 @@ // 13.1: ...cannot be overloaded if any of them, but not all, have a // ref-qualifier. +// In C++20 this was relaxed by P1787R6 "Declarations and where to find them" // { dg-require-effective-target c++11 } @@ -7,7 +8,7 @@ class Y { void h() &; void h() const &; // OK void h() &&; // OK, all declarations have a ref-qualifier - void i() &; // { dg-message "" } - void i() const; // { dg-error "" } prior declaration of i - // has a ref-qualifier + void i() &; // { dg-message "" "" { target c++17_down } } + void i() const; // { dg-error "" "" { target c++17_down } } + // prior declaration of i has a ref-qualifier }; -- 2.47.3