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

Reply via email to