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

Reply via email to