On 7/24/25 6:59 AM, Iain Sandoe wrote:
   return machinery to return the g_r_o_o_a_f.

I think it should be simpler/cleaner to move the grooaf case to the 'else' 
rather than the 'then', to accommodate the NRVO limitation described in 
check_return_expr:

Done.

same type.

We should check (gcc_checking_assert?) that NRVO works in the case where we 
expect it to, rather than let NRVO failures show up as wrong-code.

This seems a simple request - but it seems quite involved to implement;
the conditions that have to be met are numerous - I've made an attempt (that
does not regress any of the current testsuite) - but it seems potentially
fragile.

It should work to check current_function_return_value == gro (after both returns).

@@ -5423,9 +5432,43 @@ cp_coroutine_transform::build_ramp_function ()
    /* The ramp is done, we just need the return statement, which we build from
       the return object we constructed before we called the actor.  */
- r = void_ramp_p ? NULL_TREE : convert_from_reference (coro_gro);
-  finish_return_stmt (r);
-
+  if (grooaf)
+    {
+      /* This is our 'normal' exit.  */
+      r = void_ramp_p ? NULL_TREE : convert_from_reference (coro_gro);
+      r = finish_return_stmt (r);
+      /* Check that we did NRV when expected.  */
+      gcc_checking_assert (void_ramp_p
+                          || !same_type_p (gro_type, fn_return_type)
+                          || !aggregate_value_p (fn_return_type,
+                                                 current_function_decl)
+                          || return_init_is_nrv (r));

The above is the same between the if and else, why not leave it outside the if?

+      finish_compound_stmt (alloc_ok_scope);
+      finish_then_clause (grooaf_if_stmt);
+
+      begin_else_clause (grooaf_if_stmt);
+      /* We come here if the frame allocation failed.  */
+      r = NULL_TREE;
+      if (void_ramp_p)
+       /* Execute the get-return-object-on-alloc-fail call...  */
+       finish_expr_stmt (grooaf);
+      else
+       /* Get the fallback return object.  */
+       r = grooaf;
+      r = finish_return_stmt (r);
+      finish_if_stmt (grooaf_if_stmt);
+    }
+  else
+    {
+      r = void_ramp_p ? NULL_TREE : convert_from_reference (coro_gro);
+      r = finish_return_stmt (r);
+      /* Check that we did NRV when expected.  */
+      gcc_checking_assert (void_ramp_p
+                          || !same_type_p (gro_type, fn_return_type)
+                          || !aggregate_value_p (fn_return_type,
+                                                 current_function_decl)
+                          || return_init_is_nrv (r));
+    }
    finish_compound_stmt (ramp_fnbody);
    return true;
  }

Reply via email to