diff options
author | Iain Sandoe <iain@sandoe.co.uk> | 2024-08-17 16:55:29 +0100 |
---|---|---|
committer | Iain Sandoe <iain@sandoe.co.uk> | 2024-08-24 19:54:53 +0100 |
commit | f4915e6c4cd42e7d6f397dc36fab507cc47dad05 (patch) | |
tree | 44abf2a7f4f5be7f42be9748f915c2832b6804a3 /gcc | |
parent | a0b431033c307982123abbff752045cfe7eda47f (diff) | |
download | gcc-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.cc | 19 | ||||
-rw-r--r-- | 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 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 (); +} |