https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121055
Bug ID: 121055 Summary: [15/16 Regression] __is_invocable built-in doesn't match std::invoke for rvalue-ref qualified member function Product: gcc Version: 15.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: redi at gcc dot gnu.org Target Milestone: --- #include <functional> struct F { void operator()() && { } }; template<class T> void test(T t) { auto pmf = &T::operator(); if constexpr (std::is_invocable_v<void (T::*)()&&, std::reference_wrapper<T>>) std::invoke(pmf, std::ref(t)); } int main() { F f; test(f); } This compiles successfully with GCC 14 or with Clang+libstdc++, but fails with GCC 15 and GCC 16 because is_invocable_v uses the new __is_invocable built-in. The GCC built-in incorrectly returns true, so we try to do the std::invoke call, which is ill-formed: invoke.cc: In instantiation of 'void test(T) [with T = F]': invoke.cc:19:7: required from here 19 | test(f); | ~~~~^~~ invoke.cc:13:16: error: no matching function for call to 'invoke(void (F::*&)() &&, std::reference_wrapper<F>)' 13 | std::invoke(pmf, std::ref(t)); | ~~~~~~~~~~~^~~~~~~~~~~~~~~~~~ invoke.cc:13:16: note: there is 1 candidate In file included from invoke.cc:1: /home/jwakely/gcc/16/include/c++/16.0.0/functional:121:5: note: candidate 1: 'template<class _Callable, class ... _Args> std::invoke_result_t<_Callable, _Args ...> std::invoke(_Callable&&, _Args&& ...)' 121 | invoke(_Callable&& __fn, _Args&&... __args) | ^~~~~~ /home/jwakely/gcc/16/include/c++/16.0.0/functional:121:5: note: template argument deduction/substitution failed: In file included from /home/jwakely/gcc/16/include/c++/16.0.0/bits/move.h:37, from /home/jwakely/gcc/16/include/c++/16.0.0/bits/stl_function.h:60, from /home/jwakely/gcc/16/include/c++/16.0.0/functional:51: /home/jwakely/gcc/16/include/c++/16.0.0/type_traits: In substitution of 'template<class _Fn, class ... _Args> using std::invoke_result_t = typename std::invoke_result::type [with _Fn = void (F::*&)() &&; _Args = {std::reference_wrapper<F>}]': /home/jwakely/gcc/16/include/c++/16.0.0/functional:121:5: required by substitution of 'template<class _Callable, class ... _Args> std::invoke_result_t<_Callable, _Args ...> std::invoke(_Callable&&, _Args&& ...) [with _Callable = void (F::*&)() &&; _Args = {std::reference_wrapper<F>}]' invoke.cc:13:16: required from 'void test(T) [with T = F]' 13 | std::invoke(pmf, std::ref(t)); | ~~~~~~~~~~~^~~~~~~~~~~~~~~~~~ invoke.cc:19:7: required from here 19 | test(f); | ~~~~^~~ /home/jwakely/gcc/16/include/c++/16.0.0/type_traits:3360:11: error: no type named 'type' in 'struct std::invoke_result<void (F::*&)() &&, std::reference_wrapper<F> >' 3360 | using invoke_result_t = typename invoke_result<_Fn, _Args...>::type; | ^~~~~~~~~~~~~~~ The built-in should not say it's invocable.