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

--- Comment #14 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
So, I've tried
--- gcc/coroutines.cc.jj        2025-02-04 09:16:42.820267205 +0100
+++ gcc/coroutines.cc   2025-03-04 11:42:28.004682770 +0100
@@ -5183,6 +5183,15 @@ cp_coroutine_transform::build_ramp_funct
         of the relevant function.  Here we carry out the first part of
         finish_return_expr().  */
       input_location = fn_start;
+      if (!aggregate_value_p (gro_type, orig_fn_decl))
+       {
+         /* If get_ro doesn't need to be returned in memory, force it into
+            a TARGET_EXPR and try to return TARGET_EXPR_SLOT of it.  See
+            PR118874.  */
+         get_ro = force_target_expr (gro_type, get_ro, tf_warning_or_error);
+         finish_expr_stmt (get_ro);
+         get_ro = TARGET_EXPR_SLOT (get_ro);
+       }
       r = check_return_expr (get_ro, &no_warning, &dangling);
       input_location = UNKNOWN_LOCATION;
       gcc_checking_assert (!dangling);
but that actually makes things even worse, not better.
Before that change gimple dump was
        _3 = &_Coro_frameptr->_Coro_promise;
        <retval> = C::promise_type::get_return_object (_3);
        bar (_Coro_frameptr);
        return <retval>;
(which is undesirable, we IMO really want for the !aggregate_value_p initialize
a temporary VAR_DECL with what get_return_object returns, then call bar
(_Coro_frameptr); and then return that_temporary;
But with the above patch it emits
        try
          {
            _3 = &_Coro_frameptr->_Coro_promise;
            D.8886 = C::promise_type::get_return_object (_3);
          }
        finally
          {
            D.8886 = {CLOBBER(eos)};
          }
        <retval> = D.8886;
        bar (_Coro_frameptr);
        return <retval>;
which still ICEs the same way but also clobbers the temporary before it is
copied.

Reply via email to