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.