The following code fails to compile under GCC 10.0 and GCC trunk. Compile with -fcoroutines -std=c++2a See https://godbolt.org/z/zB_RVC This code compiles successfully under both Clang and MSVC coroutines implementations. ------------- #include <coroutine> struct task { struct promise_type { task get_return_object(); void return_void(); void unhandled_exception(); std::suspend_always initial_suspend() noexcept; std::suspend_always final_suspend() noexcept; }; }; struct move_only { move_only(); move_only(const move_only&) = delete; move_only(move_only&) = delete; move_only(move_only&&) = default; }; task f(move_only x) { co_return; } --------------------- Fails with compile-error: <source>: In function 'task f(move_only)': <source>:30:1: error: use of deleted function 'move_only::move_only(const move_only&)' 30 | } | ^ <source>:24:5: note: declared here 24 | move_only(move_only&) = delete; | ^~~~~~~~~ When copying parameters into the coroutine frame which are passed by value it should be initialising the parameter copy using an xvalue referring to the original function parameter. Whereas it seems like GCC is attempting to initialise the parameter-copy with an lvalue-reference to the original parameter, which ends up calling the copy-constructor. See http://eel.is/c++draft/dcl.fct.def.coroutine#13 > ... the copy is a variable of type cv T with automatic storage duration > that is direct-initialized from an xvalue of type T referring to the > parameter ...
thanks for the report, I have a fix for this in my patch queue (but the reproducer test-case is very useful).
The master branch has been updated by Iain D Sandoe <iains@gcc.gnu.org>: https://gcc.gnu.org/g:88f48e2967ead9be262483618238efa9c7c842ec commit r11-773-g88f48e2967ead9be262483618238efa9c7c842ec Author: Iain Sandoe <iain@sandoe.co.uk> Date: Mon Jun 1 08:28:35 2020 +0100 coroutines: Correct handling of references in parm copies [PR95350]. Adjust to handle rvalue refs the same way as clang, and to correct the handling of moves when a copy CTOR is present. This is one area where we could make things easier for the end-user (as was implemented before this change), however there needs to be agreement about when the full statement containing a coroutine call ends (i.e. when the ramp terminates or when the coroutine terminates). gcc/cp/ChangeLog: PR c++/95350 * coroutines.cc (struct param_info): Remove rv_ref field. (build_actor_fn): Remove specifial rvalue ref handling. (morph_fn_to_coro): Likewise. gcc/testsuite/ChangeLog: PR c++/95350 * g++.dg/coroutines/torture/func-params-08.C: Adjust test to reflect that all rvalue refs are dangling. * g++.dg/coroutines/torture/func-params-09-awaitable-parms.C: Likewise. * g++.dg/coroutines/pr95350.C: New test.
The releases/gcc-10 branch has been updated by Iain D Sandoe <iains@gcc.gnu.org>: https://gcc.gnu.org/g:284f809ef7fe8fa6b518c103d31e514a98f0f36e commit r10-8285-g284f809ef7fe8fa6b518c103d31e514a98f0f36e Author: Iain Sandoe <iain@sandoe.co.uk> Date: Fri Jun 12 08:28:35 2020 +0100 coroutines: Correct handling of references in parm copies [PR95350]. Adjust to handle rvalue refs the same way as clang, and to correct the handling of moves when a copy CTOR is present. This is one area where we could make things easier for the end-user (as was implemented before this change), however there needs to be agreement about when the full statement containing a coroutine call ends (i.e. when the ramp terminates or when the coroutine terminates). gcc/cp/ChangeLog: PR c++/95350 * coroutines.cc (struct param_info): Remove rv_ref field. (build_actor_fn): Remove specifial rvalue ref handling. (morph_fn_to_coro): Likewise. gcc/testsuite/ChangeLog: PR c++/95350 * g++.dg/coroutines/torture/func-params-08.C: Adjust test to reflect that all rvalue refs are dangling. * g++.dg/coroutines/torture/func-params-09-awaitable-parms.C: Likewise. * g++.dg/coroutines/pr95350.C: New test. (cherry picked from commit 88f48e2967ead9be262483618238efa9c7c842ec)
fixed for maater and 10.2.