https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102065
Bug ID: 102065 Summary: [C++20] Substitution failure of function instantiates its argument Product: gcc Version: 11.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: seredinyegor at gmail dot com Target Milestone: --- Created attachment 51356 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=51356&action=edit preprocessed file Problem can be reproduced with: - gcc version 11.2.0 (Ubuntu 11.2.0-1ubuntu2) - gcc version 12.0.0 20210825 (experimental) (GCC) Problem doesn't exist in: - gcc version 10.3.0 (Ubuntu 10.3.0-1ubuntu1~20.04) - Ubuntu clang version 13.0.0-++20210823084033+1f0b043ae709-1~exp1~20210823184829.58 CXXFLAGS: -std=c++20 Code: #include <functional> void elem_func(int) {} template < typename Sequence, std::invocable<int> SequenceHandler > void func( const Sequence& values, SequenceHandler&& handler, std::enable_if_t<std::is_pointer_v<Sequence>, int> = 0) { } template < typename T, std::invocable<T> ValueHandler > void func( T value, ValueHandler&& handler, std::enable_if_t<!std::is_pointer_v<T>, int> = 0) { } int main() { func( new int[1], // pointer => 1st func should be called [](auto e) // lambda should be std::invocable<int> => decltype(e)==int { elem_func(e); // cannot call elem_func if decltype(e)==int* (2nd func) } ); } Compiler output: sfinae_bug.cpp: In instantiation of ‘main()::<lambda(auto:3)> [with auto:3 = int*]’: /usr/include/c++/11/type_traits:2466: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:3)>; _Args = {int*}]’ /usr/include/c++/11/type_traits:2477:55: required from ‘struct std::__result_of_impl<false, false, main()::<lambda(auto:3)>, int*>’ /usr/include/c++/11/type_traits:2937: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:3)>, int*>; _Ret = void]’ /usr/include/c++/11/type_traits:2937:12: required from ‘struct std::is_invocable<main()::<lambda(auto:3)>, int*>’ /usr/include/c++/11/type_traits:3001:73: required from ‘constexpr const bool std::is_invocable_v<main()::<lambda(auto:3)>, int*>’ /usr/include/c++/11/concepts:338:25: required by substitution of ‘template<class T, class ValueHandler> requires invocable<ValueHandler, T> void func(T, ValueHandler&&, std::enable_if_t<(! is_pointer_v<T>), int>) [with T = int*; ValueHandler = main()::<lambda(auto:3)>]’ sfinae_bug.cpp:29:9: required from here sfinae_bug.cpp:33:23: error: invalid conversion from ‘int*’ to ‘int’ [-fpermissive] 33 | elem_func(e); // cannot call elem_func if decltype(e)==int* (2nd func) | ^ | | | int*