https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119284

            Bug ID: 119284
           Summary: Overload resolution selects wrong overload with
                    `std::invocable` concept and `auto &` in lambda
                    parameter
           Product: gcc
           Version: 14.2.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: liss.heidr...@uni-paderborn.de
  Target Milestone: ---

In the following code the wrong overload is selected if both the
`std::invocable` (1) are required and the parameter of the lambda is `auto &`
(2). Specifically, the compiler selects the `const` overload, which causes a
compiler error.
This happens in GCC-{12,13,14}.

```c++
#include <concepts>

struct S {
    void member_func() {
    }
};

template<typename F> requires (std::invocable<F, S const &>) // (1) removing
this requires clause makes this compile
void func(S const &x, F f) {
    f(x);
}

template<typename F> requires (std::invocable<F, S &>) 
void func(S &x, F f) {
    f(x);
}

int main() {
    S s;

    func(s, [](auto &x) { // (2) changing `auto &` to `S &` makes this compile
        x.member_func();
    });
}
```

## Error Message (from gcc-14)
```
<source>: In instantiation of 'main()::<lambda(auto:1&)> [with auto:1 = const
S]':
/opt/compiler-explorer/gcc-14.2.0/include/c++/14.2.0/type_traits:2640:26:  
required by substitution of 'template<class _Fn, class ... _Args> static
std::__result_of_success<decltype (declval<_Fn>()((declval<_Args>)()...)),
std::__invoke_other> std::__result_of_other_impl::_S_test(int) [with _Fn =
main()::<lambda(auto:1&)>; _Args = {const S&}]'
 2640 |       std::declval<_Fn>()(std::declval<_Args>()...)
      |       ~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~
/opt/compiler-explorer/gcc-14.2.0/include/c++/14.2.0/type_traits:2651:60:  
required from 'struct std::__result_of_impl<false, false,
main()::<lambda(auto:1&)>, const S&>'
 2651 |       using type = decltype(_S_test<_Functor, _ArgTypes...>(0));
      |                             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~
/opt/compiler-explorer/gcc-14.2.0/include/c++/14.2.0/type_traits:3159:12:  
recursively required by substitution of 'template<class _Result, class _Ret>
struct std::__is_invocable_impl<_Result, _Ret, true, std::__void_t<typename
_CTp::type> > [with _Result = std::__invoke_result<main()::<lambda(auto:1&)>,
const S&>; _Ret = void]'
 3159 |     struct is_invocable
      |            ^~~~~~~~~~~~
/opt/compiler-explorer/gcc-14.2.0/include/c++/14.2.0/type_traits:3159:12:  
required from 'struct std::is_invocable<main()::<lambda(auto:1&)>, const S&>'
/opt/compiler-explorer/gcc-14.2.0/include/c++/14.2.0/type_traits:3523:71:  
required from 'constexpr const bool
std::is_invocable_v<main()::<lambda(auto:1&)>, const S&>'
 3523 |   inline constexpr bool is_invocable_v = is_invocable<_Fn,
_Args...>::value;
      |                                                                      
^~~~~
/opt/compiler-explorer/gcc-14.2.0/include/c++/14.2.0/concepts:360:25:  
required by substitution of 'template<class F>  requires  invocable<F, const
S&> void func(const S&, F) [with F = main()::<lambda(auto:1&)>]'
  360 |     concept invocable = is_invocable_v<_Fn, _Args...>;
      |                         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<source>:21:9:   required from here
   21 |     func(s, [](auto &x) {
      |     ~~~~^~~~~~~~~~~~~~~~~
   22 |         x.member_func();
      |         ~~~~~~~~~~~~~~~~
   23 |     });
      |     ~~   
<source>:22:22: error: passing 'const S' as 'this' argument discards qualifiers
[-fpermissive]
   22 |         x.member_func();
      |         ~~~~~~~~~~~~~^~
<source>:4:10: note:   in call to 'void S::member_func()'
    4 |     void member_func() {
      |          ^~~~~~~~~~~
Compiler returned: 1
```

## Expected Behaviour
Since func is called with non-const `S`, the non-const overload should be
selected.
In the lambda `auto &` should deduce to `S &` and the requires-clause should be
satisfied.

Reply via email to