Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for trunk?
-- >8 -- 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. --- gcc/cp/method.cc | 3 ++- gcc/testsuite/g++.dg/ext/is_invocable5.C | 12 ++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/g++.dg/ext/is_invocable5.C 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..d9c0a1162fb0 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/is_invocable5.C @@ -0,0 +1,12 @@ +// 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>) ); -- 2.50.1.319.g90c0775e97