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 <[email protected]>
---
gcc/cp/coroutines.cc | 19 +++++----------
gcc/testsuite/g++.dg/coroutines/pr109682.C | 28 ++++++++++++++++++++++
2 files changed, 34 insertions(+), 13 deletions(-)
create mode 100644 gcc/testsuite/g++.dg/coroutines/pr109682.C
diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc
index d152ad20dca..64a08b49132 100644
--- a/gcc/cp/coroutines.cc
+++ b/gcc/cp/coroutines.cc
@@ -4824,25 +4824,18 @@ cp_coroutine_transform::build_ramp_function ()
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, frame_ptr_type, 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 00000000000..24aab921ab2
--- /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 ();
+}
--
2.39.2 (Apple Git-143)