From: Iain Sandoe Date: Wed, 22 Apr 2020 08:49:20 +0000 (+0100) Subject: coroutines: Pass class reference to promise param preview [PR94682] X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=38644f81babd04820daa9d622ea75eb68c066c86;p=gcc.git coroutines: Pass class reference to promise param preview [PR94682] As reported in the PR, per [dcl.fct.def.coroutine]/4 we should be passing a reference to the object to the promise parameter preview, and we are currently passing a pointer (this). Amend to pass the reference. gcc/cp/ChangeLog: 2020-04-22 Iain Sandoe PR c++/94682 * coroutines.cc (struct param_info): Add a field to note that the param is 'this'. (morph_fn_to_coro): Convert this to a reference before using it in the promise parameter preview. gcc/testsuite/ChangeLog: 2020-04-22 Iain Sandoe PR c++/94682 * g++.dg/coroutines/pr94682-preview-this.C: New test. --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 4b6691a77f0..cce017cf245 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,11 @@ +2020-04-22 Iain Sandoe + + PR c++/94682 + * coroutines.cc (struct param_info): Add a field to note that + the param is 'this'. + (morph_fn_to_coro): Convert this to a reference before using it + in the promise parameter preview. + 2020-04-22 Jason Merrill PR c++/94546 diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc index 30676eba6c2..b1d91f84cae 100644 --- a/gcc/cp/coroutines.cc +++ b/gcc/cp/coroutines.cc @@ -1760,14 +1760,15 @@ transform_await_wrapper (tree *stmt, int *do_subtree, void *d) struct param_info { - tree field_id; /* The name of the copy in the coroutine frame. */ + tree field_id; /* The name of the copy in the coroutine frame. */ vec *body_uses; /* Worklist of uses, void if there are none. */ - tree frame_type; /* The type used to represent this parm in the frame. */ - tree orig_type; /* The original type of the parm (not as passed). */ - bool by_ref; /* Was passed by reference. */ - bool rv_ref; /* Was an rvalue reference. */ - bool pt_ref; /* Was a pointer to object. */ + tree frame_type; /* The type used to represent this parm in the frame. */ + tree orig_type; /* The original type of the parm (not as passed). */ + bool by_ref; /* Was passed by reference. */ + bool rv_ref; /* Was an rvalue reference. */ + bool pt_ref; /* Was a pointer to object. */ bool trivial_dtor; /* The frame type has a trivial DTOR. */ + bool this_ptr; /* Is 'this' */ }; struct local_var_info @@ -3279,7 +3280,7 @@ morph_fn_to_coro (tree orig, tree *resumer, tree *destroyer) } else parm.frame_type = actual_type; - + parm.this_ptr = is_this_parameter (arg); parm.trivial_dtor = TYPE_HAS_TRIVIAL_DESTRUCTOR (parm.frame_type); tree pname = DECL_NAME (arg); char *buf = xasprintf ("__parm.%s", IDENTIFIER_POINTER (pname)); @@ -3617,8 +3618,21 @@ morph_fn_to_coro (tree orig, tree *resumer, tree *destroyer) false, tf_warning_or_error); /* Add this to the promise CTOR arguments list, accounting for - refs. */ - if (parm.by_ref) + refs and this ptr. */ + if (parm.this_ptr) + { + /* We pass a reference to *this to the param preview. */ + tree tt = TREE_TYPE (arg); + gcc_checking_assert (POINTER_TYPE_P (tt)); + tree ct = TREE_TYPE (tt); + 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, + 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)); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 0689f202f64..413014277c8 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2020-04-22 Iain Sandoe + + PR c++/94682 + * g++.dg/coroutines/promise-parm-preview-this.C: New test. + 2020-04-22 Christophe Lyon * lib/gcc-dg.exp (schedule-cleanups): Accept --save-temps. diff --git a/gcc/testsuite/g++.dg/coroutines/pr94682-preview-this.C b/gcc/testsuite/g++.dg/coroutines/pr94682-preview-this.C new file mode 100644 index 00000000000..ca96f373da2 --- /dev/null +++ b/gcc/testsuite/g++.dg/coroutines/pr94682-preview-this.C @@ -0,0 +1,27 @@ +#include "coro.h" + +struct promise; + +struct future +{ + using promise_type = promise; +}; + +struct promise +{ + template + promise(Class &,int) { static_assert(!std::is_pointer::value, ""); } + + coro::suspend_never initial_suspend() { return {}; } + coro::suspend_never final_suspend() { return {}; } + + future get_return_object() { return {}; } + + void return_value(int) {} + void unhandled_exception() {} +}; + +struct bar +{ + future foo(int param) { co_return 0; } +}; \ No newline at end of file