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)}; };
      |                                                     ^~~~~~~~~
  • [Bug c++/115731] New: Cor... henri.vettenranta at bitwise dot fi via Gcc-bugs

Reply via email to