https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101904
Bug ID: 101904 Summary: Wrong result of decltype during instantiation of std::result_of Product: gcc Version: 11.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: officesamurai at gmail dot com Target Milestone: --- gcc_wrong_decltype.cpp: --- #include <type_traits> struct ZZZ { template <typename Func> auto foo(Func func) -> std::result_of_t<Func(int*)> { return func(static_cast<int*>(nullptr)); } template <typename Func> auto foo(Func func) const -> std::result_of_t<Func(const int*)> { return func(static_cast<const int*>(nullptr)); } }; int main() { const ZZZ zzz; zzz.foo( [&](auto* pointer) // specifying the return type explicitly will fix the issue //-> void { static_assert(std::is_same_v<decltype(pointer), const int*>, ""); }); } --- Compiler invocation: --- $ g++-11.2.0 -c gcc_wrong_decltype.cpp gcc_wrong_decltype.cpp: In instantiation of ‘main()::<lambda(auto:1*)> [with auto:1 = int]’: /home/brd/soft/gcc-11.2.0/include/c++/11.2.0/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:1*)>; _Args = {int*}]’ /home/brd/soft/gcc-11.2.0/include/c++/11.2.0/type_traits:2477:55: required from ‘struct std::__result_of_impl<false, false, main()::<lambda(auto:1*)>, int*>’ /home/brd/soft/gcc-11.2.0/include/c++/11.2.0/type_traits:2482:12: required from ‘struct std::__invoke_result<main()::<lambda(auto:1*)>, int*>’ /home/brd/soft/gcc-11.2.0/include/c++/11.2.0/type_traits:2495:12: required from ‘struct std::result_of<main()::<lambda(auto:1*)>(int*)>’ /home/brd/soft/gcc-11.2.0/include/c++/11.2.0/type_traits:2530:11: required by substitution of ‘template<class _Tp> using result_of_t = typename std::result_of::type [with _Tp = main()::<lambda(auto:1*)>(int*)]’ gcc_wrong_decltype.cpp:6:10: required by substitution of ‘template<class Func> std::result_of_t<Func(int*)> ZZZ::foo(Func) [with Func = main()::<lambda(auto:1*)>]’ gcc_wrong_decltype.cpp:22:12: required from here gcc_wrong_decltype.cpp:27:32: error: static assertion failed 27 | static_assert(std::is_same_v<decltype(pointer), const int*>, ""); | ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ gcc_wrong_decltype.cpp:27:32: note: ‘std::is_same_v<int*, const int*>’ evaluates to false --- Note that 'pointer' actually points to const int (it's impossible to modify the pointee). Also, explicitly specifying the return type for the lambda fixes the issue. Compiler version: --- g++-11.2.0 -v Using built-in specs. COLLECT_GCC=g++-11.2.0 COLLECT_LTO_WRAPPER=/home/brd/soft/gcc-11.2.0/libexec/gcc/x86_64-pc-linux-gnu/11.2.0/lto-wrapper Target: x86_64-pc-linux-gnu Configured with: ./configure --prefix=/home/brd/soft/gcc-11.2.0 Thread model: posix Supported LTO compression algorithms: zlib zstd gcc version 11.2.0 (GCC) --- But the same happens with 10.3.0