aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorIain Sandoe <iain@sandoe.co.uk>2024-08-17 16:55:29 +0100
committerIain Sandoe <iain@sandoe.co.uk>2024-08-24 19:54:53 +0100
commitf4915e6c4cd42e7d6f397dc36fab507cc47dad05 (patch)
tree44abf2a7f4f5be7f42be9748f915c2832b6804a3 /gcc
parenta0b431033c307982123abbff752045cfe7eda47f (diff)
downloadgcc-f4915e6c4cd42e7d6f397dc36fab507cc47dad05.zip
gcc-f4915e6c4cd42e7d6f397dc36fab507cc47dad05.tar.gz
gcc-f4915e6c4cd42e7d6f397dc36fab507cc47dad05.tar.bz2
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 <iain@sandoe.co.uk>
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/coroutines.cc19
-rw-r--r--gcc/testsuite/g++.dg/coroutines/pr109682.C28
2 files changed, 34 insertions, 13 deletions
diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc
index e46b8b6..1a6e191 100644
--- a/gcc/cp/coroutines.cc
+++ b/gcc/cp/coroutines.cc
@@ -4761,25 +4761,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 0000000..24aab92
--- /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 ();
+}