https://gcc.gnu.org/g:1b3addb6fe05a80d5e043fbb12cc9c0cc426b0e6

commit r14-11726-g1b3addb6fe05a80d5e043fbb12cc9c0cc426b0e6
Author: Iain Sandoe <i...@sandoe.co.uk>
Date:   Sat Aug 17 16:55:29 2024 +0100

    c++, coroutines: Allow convertible get_return_on_allocation_fail [PR109682].
    
    We have been requiring the get_return_on_allocation_fail() call to have the
    same type as the ramp.  This is not intended by the standard, so relax that
    to allow anything convertible to the ramp return.
    
            PR c++/109682
    
    gcc/cp/ChangeLog:
    
            * coroutines.cc
            (cp_coroutine_transform::build_ramp_function): Allow for cases where
            get_return_on_allocation_fail has a type convertible to the ramp
            return type.
    
    gcc/testsuite/ChangeLog:
    
            * g++.dg/coroutines/pr109682.C: New test.
    
    Signed-off-by: Iain Sandoe <i...@sandoe.co.uk>
    (cherry picked from commit f4915e6c4cd42e7d6f397dc36fab507cc47dad05)

Diff:
---
 gcc/cp/coroutines.cc                       | 19 ++++++-------------
 gcc/testsuite/g++.dg/coroutines/pr109682.C | 28 ++++++++++++++++++++++++++++
 2 files changed, 34 insertions(+), 13 deletions(-)

diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc
index a6cbe07d1a28..00a016d1bd31 100644
--- a/gcc/cp/coroutines.cc
+++ b/gcc/cp/coroutines.cc
@@ -4946,25 +4946,18 @@ morph_fn_to_coro (tree orig, tree *resumer, tree 
*destroyer)
         control to the caller of the coroutine and the return value is
         obtained by a call to T::get_return_object_on_allocation_failure(),
         where T is the promise type.  */
-
-      gcc_checking_assert (same_type_p (fn_return_type, TREE_TYPE (grooaf)));
       tree if_stmt = begin_if_stmt ();
       tree cond = build1 (CONVERT_EXPR, coro_frame_ptr, nullptr_node);
       cond = build2 (EQ_EXPR, boolean_type_node, coro_fp, cond);
       finish_if_stmt_cond (cond, if_stmt);
+      r = NULL_TREE;
       if (void_ramp_p)
-       {
-         /* Execute the get-return-object-on-alloc-fail call...  */
-         finish_expr_stmt (grooaf);
-         /* ... but discard the result, since we return void.  */
-         finish_return_stmt (NULL_TREE);
-       }
+       /* Execute the get-return-object-on-alloc-fail call...  */
+       finish_expr_stmt (grooaf);
       else
-       {
-         /* Get the fallback return object.  */
-         r = build_cplus_new (fn_return_type, grooaf, tf_warning_or_error);
-         finish_return_stmt (r);
-       }
+       /* Get the fallback return object.  */
+       r = grooaf;
+      finish_return_stmt (r);
       finish_then_clause (if_stmt);
       finish_if_stmt (if_stmt);
     }
diff --git a/gcc/testsuite/g++.dg/coroutines/pr109682.C 
b/gcc/testsuite/g++.dg/coroutines/pr109682.C
new file mode 100644
index 000000000000..24aab921ab22
--- /dev/null
+++ b/gcc/testsuite/g++.dg/coroutines/pr109682.C
@@ -0,0 +1,28 @@
+
+#include <coroutine>
+#include <new>
+
+struct test
+{
+  test () {}
+  test (int) {}
+
+  struct promise_type {
+    test get_return_object () { return {}; }
+    //     vvv
+    static int get_return_object_on_allocation_failure () { return {}; }
+    std::suspend_never initial_suspend () noexcept { return {}; }
+    std::suspend_never final_suspend () noexcept { return {}; }
+    void return_void () {}
+    void unhandled_exception () {}
+  };
+};
+
+test
+f () { co_return; }
+
+int
+main ()
+{
+  f ();
+}

Reply via email to