aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorIain Sandoe <iain@sandoe.co.uk>2020-04-21 10:35:13 +0100
committerIain Sandoe <iain@sandoe.co.uk>2020-04-21 11:08:49 +0100
commitcd08718d57d1552fa2dbca96809e4915559685e7 (patch)
tree37ffcf044fd423793a76e3882d07be0dd811d3fa /gcc/cp
parente6cbe9654d14588f8bcaf267730fa4c694216eee (diff)
downloadgcc-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/ChangeLog6
-rw-r--r--gcc/cp/coroutines.cc47
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);