public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/115731] New: Coroutine lambda type is incomplete when selecting promise constructor
@ 2024-07-01 15:35 henri.vettenranta at bitwise dot fi
  2024-07-18  0:02 ` [Bug c++/115731] " ppalka at gcc dot gnu.org
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: henri.vettenranta at bitwise dot fi @ 2024-07-01 15:35 UTC (permalink / raw)
  To: gcc-bugs

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)}; };
      |                                                     ^~~~~~~~~

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [Bug c++/115731] Coroutine lambda type is incomplete when selecting promise constructor
  2024-07-01 15:35 [Bug c++/115731] New: Coroutine lambda type is incomplete when selecting promise constructor henri.vettenranta at bitwise dot fi
@ 2024-07-18  0:02 ` ppalka at gcc dot gnu.org
  2024-08-12 14:31 ` arsen at gcc dot gnu.org
  2024-08-12 15:06 ` arsen at gcc dot gnu.org
  2 siblings, 0 replies; 4+ messages in thread
From: ppalka at gcc dot gnu.org @ 2024-07-18  0:02 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115731

Patrick Palka <ppalka at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
   Last reconfirmed|                            |2024-07-18
                 CC|                            |ppalka at gcc dot gnu.org
             Status|UNCONFIRMED                 |NEW
     Ever confirmed|0                           |1

--- Comment #1 from Patrick Palka <ppalka at gcc dot gnu.org> ---
Interesting, confirmed.  It seems only non-generic lambdas are affected,
generic lambdas aren't affected because the coroutine transformation is
performed on the instantiated operator() well after completion of the lambda
type.

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [Bug c++/115731] Coroutine lambda type is incomplete when selecting promise constructor
  2024-07-01 15:35 [Bug c++/115731] New: Coroutine lambda type is incomplete when selecting promise constructor henri.vettenranta at bitwise dot fi
  2024-07-18  0:02 ` [Bug c++/115731] " ppalka at gcc dot gnu.org
@ 2024-08-12 14:31 ` arsen at gcc dot gnu.org
  2024-08-12 15:06 ` arsen at gcc dot gnu.org
  2 siblings, 0 replies; 4+ messages in thread
From: arsen at gcc dot gnu.org @ 2024-08-12 14:31 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115731

Arsen Arsenović <arsen at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |arsen at gcc dot gnu.org

--- Comment #2 from Arsen Arsenović <arsen at gcc dot gnu.org> ---
I think MSVC also is not passing the lambda to the promise type.  Removing the
default constructor from your attachment (as well as the member example in
main) leads to:

  <source>(33): error C2512: 'coro::promise_type::promise_type': no appropriate
default constructor available
  <source>(18): note: could be 'coro::promise_type::promise_type(T &&)'
  <source>(33): note: 'coro::promise_type::promise_type(T &&)': expects 1
arguments - 0 provided
  <source>(33): note: while trying to match the argument list '()'

I think this is correct, per [dcl.fct.def.coroutine]#5.7:

  promise-constructor-arguments is determined as follows: overload resolution
is performed on a promise constructor call created by assembling an argument
list q_1...q_n.
  If a viable constructor is found ([over.match.viable]), then
promise-constructor-arguments is (q_1, ..., q_n), otherwise
promise-constructor-arguments is empty, ...

... where ([dcl.fct.def.coroutine]#4):

  In the following, p_i is an lvalue of type P_i, where p_1 denotes the object
parameter and pi+1 denotes the ith non-object function parameter for an
implicit object member function, and p_i denotes the i_th function parameter
otherwise.
  For an implicit object member function, q_1 is an lvalue that denotes *this;
any other q_i is an lvalue that denotes the parameter copy corresponding to
p_i, as described below.

... but I don't think a lambda is an implicit object member function
([dcl.fct]#6) because:

  An implicit object member function is a non-static member function without an
explicit object parameter.

... so, I think the fix is to not pass that argument.

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [Bug c++/115731] Coroutine lambda type is incomplete when selecting promise constructor
  2024-07-01 15:35 [Bug c++/115731] New: Coroutine lambda type is incomplete when selecting promise constructor henri.vettenranta at bitwise dot fi
  2024-07-18  0:02 ` [Bug c++/115731] " ppalka at gcc dot gnu.org
  2024-08-12 14:31 ` arsen at gcc dot gnu.org
@ 2024-08-12 15:06 ` arsen at gcc dot gnu.org
  2 siblings, 0 replies; 4+ messages in thread
From: arsen at gcc dot gnu.org @ 2024-08-12 15:06 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115731

--- Comment #3 from Arsen Arsenović <arsen at gcc dot gnu.org> ---
ah, no, never mind - it does.  per [expr.prim.lambda]#6,

  ... Otherwise, it is a non-static member function or member function
template, ...

so, yeah, we need to complete that type, likely

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2024-08-12 15:06 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-07-01 15:35 [Bug c++/115731] New: Coroutine lambda type is incomplete when selecting promise constructor henri.vettenranta at bitwise dot fi
2024-07-18  0:02 ` [Bug c++/115731] " ppalka at gcc dot gnu.org
2024-08-12 14:31 ` arsen at gcc dot gnu.org
2024-08-12 15:06 ` arsen at gcc dot gnu.org

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).