diff options
author | Iain Sandoe <iain@sandoe.co.uk> | 2020-04-21 10:35:13 +0100 |
---|---|---|
committer | Iain Sandoe <iain@sandoe.co.uk> | 2020-04-21 11:08:49 +0100 |
commit | cd08718d57d1552fa2dbca96809e4915559685e7 (patch) | |
tree | 37ffcf044fd423793a76e3882d07be0dd811d3fa /gcc/cp | |
parent | e6cbe9654d14588f8bcaf267730fa4c694216eee (diff) | |
download | gcc-cd08718d57d1552fa2dbca96809e4915559685e7.zip gcc-cd08718d57d1552fa2dbca96809e4915559685e7.tar.gz gcc-cd08718d57d1552fa2dbca96809e4915559685e7.tar.bz2 |
coroutines: Fix handling of ramp return value [PR94661]
Coroutine ramp functions have synthesised return values (the
user-authored function body cannot have an explicit 'return').
The current implementation attempts to optimise by building
the return in-place, in the manner of C++17 code. Clearly,
that was too ambitious and the fix builds a target expr for
the constructed version and passes that to finish_return_stmt.
This also means that we now get the same error messages for
implicit use of deleted CTORs etc.
gcc/cp/ChangeLog:
2020-04-21 Iain Sandoe <iain@sandoe.co.uk>
PR c++/94661
* coroutines.cc (morph_fn_to_coro): Simplify return
value computation.
gcc/testsuite/ChangeLog:
2020-04-21 Iain Sandoe <iain@sandoe.co.uk>
PR c++/94661
* g++.dg/coroutines/ramp-return-a.C: New test.
* g++.dg/coroutines/ramp-return-b.C: New test.
* g++.dg/coroutines/ramp-return-c.C: New test.
Diffstat (limited to 'gcc/cp')
-rw-r--r-- | gcc/cp/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/coroutines.cc | 47 |
2 files changed, 21 insertions, 32 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 53daab1..5b2bff8 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2020-04-21 Iain Sandoe <iain@sandoe.co.uk> + + PR c++/94661 + * coroutines.cc (morph_fn_to_coro): Simplify return + value computation. + 2020-04-17 Marek Polacek <polacek@redhat.com> PR c++/94592 diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc index ceb8daa..30676eb 100644 --- a/gcc/cp/coroutines.cc +++ b/gcc/cp/coroutines.cc @@ -3726,23 +3726,14 @@ morph_fn_to_coro (tree orig, tree *resumer, tree *destroyer) } tree gro_context_body = push_stmt_list (); - tree gro, gro_bind_vars; - if (same_type_p (TREE_TYPE (get_ro), fn_return_type)) - { - gro = DECL_RESULT (orig); - gro_bind_vars = NULL_TREE; /* We don't need a separate var. */ - } - else - { - gro = build_lang_decl (VAR_DECL, get_identifier ("coro.gro"), - TREE_TYPE (TREE_OPERAND (get_ro, 0))); - DECL_CONTEXT (gro) = current_scope (); - r = build_stmt (fn_start, DECL_EXPR, gro); - add_stmt (r); - gro_bind_vars = gro; /* We need a temporary var. */ - } - - /* Initialize our actual var. */ + tree gro = build_lang_decl (VAR_DECL, get_identifier ("coro.gro"), + TREE_TYPE (get_ro)); + DECL_CONTEXT (gro) = current_scope (); + add_decl_expr (gro); + tree gro_bind_vars = gro; + + /* We have to sequence the call to get_return_object before initial + suspend. */ r = build2_loc (fn_start, INIT_EXPR, TREE_TYPE (gro), gro, get_ro); r = coro_build_cvt_void_expr_stmt (r, fn_start); add_stmt (r); @@ -3779,30 +3770,22 @@ morph_fn_to_coro (tree orig, tree *resumer, tree *destroyer) logically doing things related to the end of the function. */ /* The ramp is done, we just need the return value. */ - if (!same_type_p (TREE_TYPE (gro), fn_return_type)) + if (!same_type_p (TREE_TYPE (get_ro), fn_return_type)) { /* construct the return value with a single GRO param. */ vec<tree, va_gc> *args = make_tree_vector_single (gro); - r = build_special_member_call (DECL_RESULT (orig), + r = build_special_member_call (NULL_TREE, complete_ctor_identifier, &args, fn_return_type, LOOKUP_NORMAL, tf_warning_or_error); - r = coro_build_cvt_void_expr_stmt (r, input_location); - add_stmt (r); - release_tree_vector (args); + r = build_cplus_new (fn_return_type, r, tf_warning_or_error); } - /* Else the GRO is the return and we already built it in place. */ + else + r = rvalue (gro); /* The GRO is the return value. */ - bool no_warning; - r = check_return_expr (DECL_RESULT (orig), &no_warning); - if (error_operand_p (r) && warn_return_type) - /* Suppress -Wreturn-type for the ramp. */ - TREE_NO_WARNING (orig) = true; + finish_return_stmt (r); - r = build_stmt (input_location, RETURN_EXPR, DECL_RESULT (orig)); - TREE_NO_WARNING (r) |= no_warning; - r = maybe_cleanup_point_expr_void (r); - add_stmt (r); + /* Finish up the ramp function. */ BIND_EXPR_VARS (gro_context_bind) = gro_bind_vars; BIND_EXPR_BODY (gro_context_bind) = pop_stmt_list (gro_context_body); BIND_EXPR_BODY (ramp_bind) = pop_stmt_list (ramp_body); |