The expression promise.get_return_object() is used to initialize the
glvalue result or prvalue result object of a call to a coroutine. */
+ /* We must manage the cleanups ourselves, because the responsibility for
+ them changes after the initial suspend. However, any use of
+ cxx_maybe_build_cleanup () can set the throwing_cleanup flag. */
+ cp_function_chain->throwing_cleanup = false;
if (void_ramp_p)
/* We still want to call the method, even if the result is unused. */
r = get_ro;
else
{
+ /* The initial section of finish_return_expr (). */
bool no_warning;
bool dangling;
/* Without a relevant location, bad conversions in check_return_expr
body_blocks = current_binding_level->blocks;
current_binding_level->blocks = NULL_TREE;
- /* If the original function has a return value with a non-trivial DTOR
- and the body contains a var with a DTOR that might throw, the decl is
- marked "throwing_cleanup".
- We do not [in the ramp, which is synthesised here], use any body var
- types with DTORs that might throw.
- The original body is transformed into the actor function which only
- contains void returns, and is also wrapped in a try-catch block.
- So (a) the 'throwing_cleanup' is not correct for the ramp and (b) we do
- not need to transfer it to the actor which only contains void returns. */
- cp_function_chain->throwing_cleanup = false;
-
/* Collect information on the original function params and their use in the
function body. */
analyze_fn_parms (orig_fn_decl, ¶m_uses);
--- /dev/null
+#include <coroutine>
+
+struct Foo {
+ ~Foo() noexcept(false); // true succeeds
+ struct promise_type {
+ Foo get_return_object() { return {}; }
+ std::suspend_never initial_suspend() { return {}; }
+ void return_void() {}
+ void unhandled_exception() {}
+ std::suspend_always final_suspend() noexcept { return {}; }
+ };
+};
+
+Foo bar() {
+ co_return;
+}