aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIain Sandoe <iain@sandoe.co.uk>2020-04-22 09:49:20 +0100
committerIain Sandoe <iain@sandoe.co.uk>2020-04-22 09:49:20 +0100
commit38644f81babd04820daa9d622ea75eb68c066c86 (patch)
tree61495547ef6245a0200874f9d3cfec0ee10d0268
parent9ad3c1d81c129fc76594b9df5b798c380cbf03ee (diff)
downloadgcc-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/ChangeLog8
-rw-r--r--gcc/cp/coroutines.cc32
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/coroutines/pr94682-preview-this.C27
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