https://gcc.gnu.org/g:04a176a1d84a84c630cfd4d232736c12b105957a

commit r16-2447-g04a176a1d84a84c630cfd4d232736c12b105957a
Author: Patrick Palka <ppa...@redhat.com>
Date:   Wed Jul 23 08:31:46 2025 -0400

    c++: fix __is_invocable for std::reference_wrapper [PR121055]
    
    Our implementation of the INVOKE spec ([func.require]) was incorrectly
    treating reference_wrapper<T>::get() as returning T instead of T&, which
    notably makes a difference when invoking a ref-qualified memfn pointer.
    
            PR c++/121055
    
    gcc/cp/ChangeLog:
    
            * method.cc (build_invoke): Correct reference_wrapper handling.
    
    gcc/testsuite/ChangeLog:
    
            * g++.dg/ext/is_invocable5.C: New test.
    
    Reviewed-by: Jason Merrill <ja...@redhat.com>

Diff:
---
 gcc/cp/method.cc                         |  3 ++-
 gcc/testsuite/g++.dg/ext/is_invocable5.C | 15 +++++++++++++++
 2 files changed, 17 insertions(+), 1 deletion(-)

diff --git a/gcc/cp/method.cc b/gcc/cp/method.cc
index a4089c53c67b..334c325842f7 100644
--- a/gcc/cp/method.cc
+++ b/gcc/cp/method.cc
@@ -2036,10 +2036,11 @@ build_invoke (tree fn_type, const_tree arg_types, 
tsubst_flags_t complain)
              const_tree name = DECL_NAME (datum_decl);
              if (name && (id_equal (name, "reference_wrapper")))
                {
-                 /* 1.2 & 1.5: Retrieve T from std::reference_wrapper<T>,
+                 /* 1.2 & 1.5: Retrieve T& from std::reference_wrapper<T>,
                     i.e., decltype(datum.get()).  */
                  datum_type =
                    TREE_VEC_ELT (TYPE_TI_ARGS (non_ref_datum_type), 0);
+                 datum_type = cp_build_reference_type (datum_type, false);
                  datum_is_refwrap = true;
                }
            }
diff --git a/gcc/testsuite/g++.dg/ext/is_invocable5.C 
b/gcc/testsuite/g++.dg/ext/is_invocable5.C
new file mode 100644
index 000000000000..460eed595a9a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/is_invocable5.C
@@ -0,0 +1,15 @@
+// PR c++/121055
+// { dg-do compile { target c++11 } }
+// { dg-skip-if "requires hosted libstdc++ for functional function" { ! 
hostedlib } }
+
+#include <functional>
+
+#define SA(X) static_assert((X),#X)
+
+struct F;
+
+SA( __is_invocable(void (F::*)() &, std::reference_wrapper<F>) );
+SA( ! __is_invocable(void (F::*)() &&, std::reference_wrapper<F>) );
+
+SA( __is_invocable(void (F::*)(int) &, std::reference_wrapper<F>, int) );
+SA( ! __is_invocable(void (F::*)(int) &&, std::reference_wrapper<F>, int) );

Reply via email to