https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115731
Bug ID: 115731 Summary: Coroutine lambda type is incomplete when selecting promise constructor Product: gcc Version: 11.4.0 Status: UNCONFIRMED Keywords: C++-coroutines, c++-lambda Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: henri.vettenranta at bitwise dot fi Target Milestone: --- Created attachment 58551 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=58551&action=edit Reproduction of the problem When selecting the coroutine promise constructor for a lambda that is a coroutine, the type of the lambda class is still incomplete. This can cause hard (non-SFINAE) compile errors with concept requires clauses that require the type to be complete, such as std::derived_from, even if the constructor in question is not the one desired by the programmer. I am not sure if this behaviour is against the C++ standard, but it is a cumbersome limitation. It is also inconsistent with any other member function, because a function is only known to be a coroutine when its definition is being compiled, and for any other function, including class members whose definition was written inline in the class definition, the definition is only compiled once the class is complete. MSVC compiles the example code; Clang also compiles it, although this is because Clang does not pass the lambda *this reference to the coroutine promise constructor in the first place. Preprocessed header in attachment, Godbolt link to the same reproduction case: https://godbolt.org/z/Ybo6nzevM . remove_reference_t is used in the requires clause due to bug 115550. Note that there is no error for the operator() coroutine member of a class, only for the lambda. The error message can be reproduced on GCC 14.1. g++ -v -Wall -Wextra -Wpedantic -std=c++20 -c -o /dev/null gcc-lambda-incomplete.i Using built-in specs. COLLECT_GCC=g++ OFFLOAD_TARGET_NAMES=nvptx-none:amdgcn-amdhsa OFFLOAD_TARGET_DEFAULT=1 Target: x86_64-linux-gnu Configured with: ../src/configure -v --with-pkgversion='Ubuntu 11.4.0-1ubuntu1~22.04' --with-bugurl=file:///usr/share/doc/gcc-11/README.Bugs --enable-languages=c,ada,c++,go,brig,d,fortran,objc,obj-c++,m2 --prefix=/usr --with-gcc-major-version-only --program-suffix=-11 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-bootstrap --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-plugin --enable-default-pie --with-system-zlib --enable-libphobos-checking=release --with-target-system-zlib=auto --enable-objc-gc=auto --enable-multiarch --disable-werror --enable-cet --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none=/build/gcc-11-XeT9lY/gcc-11-11.4.0/debian/tmp-nvptx/usr,amdgcn-amdhsa=/build/gcc-11-XeT9lY/gcc-11-11.4.0/debian/tmp-gcn/usr --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu --with-build-config=bootstrap-lto-lean --enable-link-serialization=2 Thread model: posix Supported LTO compression algorithms: zlib zstd gcc version 11.4.0 (Ubuntu 11.4.0-1ubuntu1~22.04) COLLECT_GCC_OPTIONS='-v' '-Wall' '-Wextra' '-Wpedantic' '-std=c++20' '-c' '-o' '/dev/null' '-shared-libgcc' '-mtune=generic' '-march=x86-64' /usr/lib/gcc/x86_64-linux-gnu/11/cc1plus -fpreprocessed gcc-lambda-incomplete.i -quiet -dumpbase gcc-lambda-incomplete.i -dumpbase-ext .i -mtune=generic -march=x86-64 -Wall -Wextra -Wpedantic -std=c++20 -version -fasynchronous-unwind-tables -fstack-protector-strong -Wformat-security -fstack-clash-protection -fcf-protection -o /tmp/ccZjqOyB.s GNU C++20 (Ubuntu 11.4.0-1ubuntu1~22.04) version 11.4.0 (x86_64-linux-gnu) compiled by GNU C version 11.4.0, GMP version 6.2.1, MPFR version 4.1.0, MPC version 1.2.1, isl version isl-0.24-GMP GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072 GNU C++20 (Ubuntu 11.4.0-1ubuntu1~22.04) version 11.4.0 (x86_64-linux-gnu) compiled by GNU C version 11.4.0, GMP version 6.2.1, MPFR version 4.1.0, MPC version 1.2.1, isl version isl-0.24-GMP GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072 Compiler executable checksum: d591828bb4d392ae8b7b160e5bb0b95f gcc-lambda-incomplete.cpp: In instantiation of ‘constexpr const int mysizeof<const main()::<lambda()>&>::value’: gcc-lambda-incomplete.cpp:18:52: required by substitution of ‘template<class T> requires (mysizeof<typename remove_reference<T>::type>::value) > 100 coro::promise_type::promise_type(T&&) [with T = const main()::<lambda()>&&]’ gcc-lambda-incomplete.cpp:43:32: required from here gcc-lambda-incomplete.cpp:9:53: error: invalid application of ‘sizeof’ to incomplete type ‘const main()::<lambda()>’ 9 | struct mysizeof { static inline constexpr int value{sizeof(T)}; }; | ^~~~~~~~~