On 5/13/25 10:30 AM, Iain Sandoe wrote:
This addresses the clarification that, when the get_return_object is of a
different type from the ramp return, any necessary conversions should be
performed on the return expression (so that they typically occur after the
function body has started execution).
PR c++/119916
gcc/cp/ChangeLog:
* coroutines.cc
(cp_coroutine_transform::wrap_original_function_body): Do not
initialise initial_await_resume_called here...
(cp_coroutine_transform::build_ramp_function): ... but here.
When the coroutine is not void, initialize a GRO object from
promise.get_return_object(). Use this as the argument to the
return expression. Use a regular cleanup for the GRO, since
it is ramp-local.
gcc/testsuite/ChangeLog:
* g++.dg/coroutines/torture/special-termination-00-sync-completion.C:
Amend for CWG2563 expected behaviour.
* g++.dg/coroutines/torture/special-termination-01-self-destruct.C:
Likewise.
* g++.dg/coroutines/torture/pr119916.C: New test.
Signed-off-by: Iain Sandoe <i...@sandoe.co.uk>
+ /* We must manage the cleanups ourselves, because the responsibility for
+ them changes after the initial suspend. However, any use of
+ cxx_maybe_build_cleanup () can set the throwing_cleanup flag. */
+ cp_function_chain->throwing_cleanup = false;
Hmm...what if the gro cleanup throws after initializing the (different
type) return value? That seems like a case that we need
throwing_cleanup set for.
@@ -5245,8 +5195,11 @@ cp_coroutine_transform::build_ramp_function ()
tree not_iarc
= build1_loc (loc, TRUTH_NOT_EXPR, boolean_type_node, iarc_x);
+ tree do_cleanup = build2_loc (loc, TRUTH_AND_EXPR, boolean_type_node,
+ not_iarc, coro_before_return);
As with the 14 patch, this should be reversed.
Jason