public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r10-9511] coroutines : Call promise CTOR with parm copies [PR97587].
@ 2021-03-22 22:03 Iain D Sandoe
0 siblings, 0 replies; only message in thread
From: Iain D Sandoe @ 2021-03-22 22:03 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:88bb77a8dcf75f556b8dcb24b8785b4567d24e4f
commit r10-9511-g88bb77a8dcf75f556b8dcb24b8785b4567d24e4f
Author: Iain Sandoe <iain@sandoe.co.uk>
Date: Mon Feb 15 16:13:36 2021 +0000
coroutines : Call promise CTOR with parm copies [PR97587].
As the PR notes, we were calling the promise CTOR with the original
function parameters, not the copy (as pointed, a previous wording of
the section was unambiguous). Fixed thus.
gcc/cp/ChangeLog:
PR c++/97587
* coroutines.cc (struct param_info): Track rvalue refs.
(morph_fn_to_coro): Track rvalue refs, and call the promise
CTOR with the frame copy of passed parms.
gcc/testsuite/ChangeLog:
PR c++/97587
* g++.dg/coroutines/coro1-refs-and-ctors.h: Add a CTOR with two
reference parms, to distinguish the rvalue ref. variant.
* g++.dg/coroutines/pr97587.C: New test.
(cherry picked from commit b8ff3f8efeda02a6bedebfaf20b93645ae3bb5b8)
Diff:
---
gcc/cp/coroutines.cc | 25 +++++++++++------
.../g++.dg/coroutines/coro1-refs-and-ctors.h | 7 +++--
gcc/testsuite/g++.dg/coroutines/pr97587.C | 32 ++++++++++++++++++++++
3 files changed, 54 insertions(+), 10 deletions(-)
diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc
index f107e6fbb87..3a2c4fb930c 100644
--- a/gcc/cp/coroutines.cc
+++ b/gcc/cp/coroutines.cc
@@ -1833,6 +1833,7 @@ struct param_info
tree orig_type; /* The original type of the parm (not as passed). */
bool by_ref; /* Was passed by reference. */
bool pt_ref; /* Was a pointer to object. */
+ bool rv_ref; /* Was an rvalue ref. */
bool trivial_dtor; /* The frame type has a trivial DTOR. */
bool this_ptr; /* Is 'this' */
bool lambda_cobj; /* Lambda capture object */
@@ -4139,7 +4140,7 @@ morph_fn_to_coro (tree orig, tree *resumer, tree *destroyer)
if (actual_type == NULL_TREE)
actual_type = error_mark_node;
parm.orig_type = actual_type;
- parm.by_ref = parm.pt_ref = false;
+ parm.by_ref = parm.pt_ref = parm.rv_ref = false;
if (TREE_CODE (actual_type) == REFERENCE_TYPE)
{
/* If the user passes by reference, then we will save the
@@ -4147,8 +4148,10 @@ morph_fn_to_coro (tree orig, tree *resumer, tree *destroyer)
[dcl.fct.def.coroutine] / 13, if the lifetime of the
referenced item ends and then the coroutine is resumed,
we have UB; well, the user asked for it. */
- actual_type = build_pointer_type (TREE_TYPE (actual_type));
- parm.pt_ref = true;
+ if (TYPE_REF_IS_RVALUE (actual_type))
+ parm.rv_ref = true;
+ else
+ parm.pt_ref = true;
}
else if (TYPE_REF_P (DECL_ARG_TYPE (arg)))
parm.by_ref = true;
@@ -4524,16 +4527,22 @@ morph_fn_to_coro (tree orig, tree *resumer, tree *destroyer)
tree this_ref = build1 (INDIRECT_REF, ct, arg);
tree rt = cp_build_reference_type (ct, false);
this_ref = convert_to_reference (rt, this_ref, CONV_STATIC,
- LOOKUP_NORMAL , NULL_TREE,
+ LOOKUP_NORMAL, NULL_TREE,
tf_warning_or_error);
vec_safe_push (promise_args, this_ref);
}
- else if (parm.by_ref)
- vec_safe_push (promise_args, fld_idx);
+ else if (parm.rv_ref)
+ vec_safe_push (promise_args, rvalue(fld_idx));
else
- vec_safe_push (promise_args, arg);
+ vec_safe_push (promise_args, fld_idx);
- if (TYPE_NEEDS_CONSTRUCTING (parm.frame_type))
+ if (parm.rv_ref || parm.pt_ref)
+ /* Initialise the frame reference field directly. */
+ r = build_modify_expr (fn_start, TREE_OPERAND (fld_idx, 0),
+ parm.frame_type, INIT_EXPR,
+ DECL_SOURCE_LOCATION (arg), arg,
+ DECL_ARG_TYPE (arg));
+ else if (TYPE_NEEDS_CONSTRUCTING (parm.frame_type))
{
vec<tree, va_gc> *p_in;
if (CLASS_TYPE_P (parm.frame_type)
diff --git a/gcc/testsuite/g++.dg/coroutines/coro1-refs-and-ctors.h b/gcc/testsuite/g++.dg/coroutines/coro1-refs-and-ctors.h
index 8831a07875e..dd45a0e1f81 100644
--- a/gcc/testsuite/g++.dg/coroutines/coro1-refs-and-ctors.h
+++ b/gcc/testsuite/g++.dg/coroutines/coro1-refs-and-ctors.h
@@ -3,10 +3,13 @@ struct coro1 {
struct promise_type {
promise_type () : vv(-1) { PRINT ("Promise def. CTOR"); }
- promise_type (int __x) : vv(__x) { PRINTF ("Created Promise with %d\n",__x); }
+ promise_type (int __x) : vv(__x) { PRINTF ("promise_type1 with %d\n",__x); }
promise_type (int __x, int& __y, int&& __z)
: vv(__x), v2(__y), v3(__z)
- { PRINTF ("Created Promise with %d, %d, %d\n", __x, __y, __z); }
+ { PRINTF ("promise_type2 with %d, %d, %d\n", __x, __y, __z); }
+ promise_type (int __x, int& __y, int& __z)
+ : vv(__x), v2(__y), v3(__z)
+ { PRINTF ("promise_type3 with %d, %d, %d\n", __x, __y, __z); }
~promise_type() { PRINT ("Destroyed Promise"); }
diff --git a/gcc/testsuite/g++.dg/coroutines/pr97587.C b/gcc/testsuite/g++.dg/coroutines/pr97587.C
new file mode 100644
index 00000000000..081c3a94b3c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/coroutines/pr97587.C
@@ -0,0 +1,32 @@
+// { dg-do run }
+
+#include<cassert>
+#include<coroutine>
+
+int *parameter_addr_in_promise_ctor;
+
+struct return_object{
+ struct promise_type{
+
+ promise_type(int ¶meter)
+ {
+ parameter_addr_in_promise_ctor = ¶meter;
+ }
+
+ return_object get_return_object(){ return {}; }
+
+ void return_void(){}
+
+ auto initial_suspend(){ return std::suspend_never{}; }
+ auto final_suspend() noexcept { return std::suspend_never{}; }
+ void unhandled_exception(){}
+ };
+};
+return_object coroutine(int parameter = 42){
+ assert(¶meter == parameter_addr_in_promise_ctor);
+ co_return;
+}
+
+int main(int,char**){
+ coroutine();
+}
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2021-03-22 22:03 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-03-22 22:03 [gcc r10-9511] coroutines : Call promise CTOR with parm copies [PR97587] Iain D Sandoe
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).