diff options
author | Iain Sandoe <iain@sandoe.co.uk> | 2020-04-22 09:49:20 +0100 |
---|---|---|
committer | Iain Sandoe <iain@sandoe.co.uk> | 2020-04-22 09:49:20 +0100 |
commit | 38644f81babd04820daa9d622ea75eb68c066c86 (patch) | |
tree | 61495547ef6245a0200874f9d3cfec0ee10d0268 | |
parent | 9ad3c1d81c129fc76594b9df5b798c380cbf03ee (diff) | |
download | gcc-38644f81babd04820daa9d622ea75eb68c066c86.zip gcc-38644f81babd04820daa9d622ea75eb68c066c86.tar.gz gcc-38644f81babd04820daa9d622ea75eb68c066c86.tar.bz2 |
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 <iain@sandoe.co.uk>
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 <iain@sandoe.co.uk>
PR c++/94682
* g++.dg/coroutines/pr94682-preview-this.C: New test.
-rw-r--r-- | gcc/cp/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/cp/coroutines.cc | 32 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/coroutines/pr94682-preview-this.C | 27 |
4 files changed, 63 insertions, 9 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 4b6691a..cce017c 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,11 @@ +2020-04-22 Iain Sandoe <iain@sandoe.co.uk> + + 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 <jason@redhat.com> PR c++/94546 diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc index 30676eb..b1d91f8 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<tree *> *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 0689f20..4130142 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2020-04-22 Iain Sandoe <iain@sandoe.co.uk> + + PR c++/94682 + * g++.dg/coroutines/promise-parm-preview-this.C: New test. + 2020-04-22 Christophe Lyon <christophe.lyon@linaro.org> * 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 0000000..ca96f37 --- /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<typename Class> + promise(Class &,int) { static_assert(!std::is_pointer<Class>::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 |