https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94661
Bug ID: 94661 Summary: coroutine ramp function return value ICE for default copy CTOR. Product: gcc Version: 10.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: iains at gcc dot gnu.org Target Milestone: --- Created attachment 48307 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=48307&action=edit fix being tested Coroutine ramp functions have synthesised return values (the user-authored function body cannot have an explicit 'return'). The current implementation attempts to optimise by building the return in-place, in the manner of C++17 code. Clearly, too ambitious : The following code ICEs with internal compiler error: in expand_expr_addr_expr_1, at expr.c:8075 This is because the default copy CTOR conflicts with the inlace construction. (NOTE: If the Copy CTOR is marked as deleted [which is the most common programming idiom for this] all is OK). --- template <typename T> struct promise { T _value; coro::coroutine_handle<> _continuation = nullptr; struct final_awaitable { bool _has_continuation; final_awaitable(bool has_continuation) : _has_continuation(has_continuation) {} bool await_ready() const noexcept { return !_has_continuation; } template <typename Promise> coro::coroutine_handle<> await_suspend(coro::coroutine_handle<Promise> coro) noexcept { return coro.promise()._continuation; } void await_resume() noexcept {} }; auto get_return_object() noexcept { return coro::coroutine_handle<promise>::from_promise(*this); } auto initial_suspend() noexcept { return coro::suspend_always(); } auto final_suspend() noexcept { return final_awaitable(_continuation != nullptr); } void return_value(T value) { _value = value; } void unhandled_exception() { /*std::terminate();*/ } }; template <typename T> struct task { using promise_type = promise<T>; coro::coroutine_handle<promise<T>> _handle; task(coro::coroutine_handle<promise<T>> handle) : _handle(handle) {} bool await_ready() noexcept { return _handle.done(); } coro::coroutine_handle<> await_suspend(coro::coroutine_handle<> handle) noexcept { _handle.promise()._continuation = handle; return _handle; } T await_resume() noexcept { return _handle.promise()._value; } }; task<int> foo() { co_return 1; }