aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/class.c
diff options
context:
space:
mode:
authorIain Sandoe <iain@sandoe.co.uk>2020-02-26 13:28:07 +0000
committerIain Sandoe <iain@sandoe.co.uk>2020-02-26 20:42:42 +0000
commitdc192bbdd0442f75e324cc82a98e611b7912e2f9 (patch)
tree83e8b11aec1912dbdf853b717a3409cb3c15fead /gcc/cp/class.c
parentc5decc83e4eb06103c801fd4f8215301ce746109 (diff)
downloadgcc-dc192bbdd0442f75e324cc82a98e611b7912e2f9.zip
gcc-dc192bbdd0442f75e324cc82a98e611b7912e2f9.tar.gz
gcc-dc192bbdd0442f75e324cc82a98e611b7912e2f9.tar.bz2
coroutines: Amend parameter handling to match n4849.
In n4849 and preceding versions, [class.copy.elision] (1.3) appears to confer additional permissions on coroutines to elide parameter copies. After considerable discussion on this topic by email and during the February 2020 WG21 meeting, it has been determined that there are no additional permissions applicable to coroutine parameter copy elision. The content of that clause in the standard is expected to be amended eventually to clarify this. Other than this, the handling of parameter lifetimes is expected to be as per n4849: * A copy is made before the promise is constructed * If the promise CTOR uses the parms, then it should use the copy where appropriate. * The param copy lifetimes end after the promise is destroyed (during the coroutine frame destruction). * Otherwise, C++20 copy elision rules apply. (as an aside) In practice, we expect that copy elision can only occur when the coroutine body is fully inlined, possibly in conjunction with heap allocation elision. The patch: * Reorders the copying process to precede the promise CTOR and ensures the correct use. * Copies all params into the frame regardless of whether the coro body uses them (this is a bit unfortunate, and we should figure out an amendment for C++23). gcc/cp/ChangeLog: 2020-02-26 Iain Sandoe <iain@sandoe.co.uk> * class.c (classtype_has_non_deleted_copy_ctor): New. * coroutines.cc (struct param_info): Keep track of params that are references, and cache the original type and whether the DTOR is trivial. (build_actor_fn): Handle param copies always, and adjust the handling for references. (register_param_uses): Only handle uses here. (classtype_has_non_deleted_copy_ctor): New. (morph_fn_to_coro): Adjust param copy handling to match n4849 by reordering ahead of the promise CTOR and always making a frame copy, even if the param is unused in the coroutine body. * cp-tree.h (classtype_has_non_deleted_copy_ctor): New. gcc/testsuite/ChangeLog: 2020-02-26 Iain Sandoe <iain@sandoe.co.uk> * g++.dg/coroutines/coro1-refs-and-ctors.h: New. * g++.dg/coroutines/torture/func-params-07.C: New test. * g++.dg/coroutines/torture/func-params-08.C: New test.
Diffstat (limited to 'gcc/cp/class.c')
-rw-r--r--gcc/cp/class.c13
1 files changed, 13 insertions, 0 deletions
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 772134d..6b779da 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -5447,6 +5447,19 @@ classtype_has_non_deleted_move_ctor (tree t)
return false;
}
+/* True iff T has a copy constructor that is not deleted. */
+
+bool
+classtype_has_non_deleted_copy_ctor (tree t)
+{
+ if (CLASSTYPE_LAZY_COPY_CTOR (t))
+ lazily_declare_fn (sfk_copy_constructor, t);
+ for (ovl_iterator iter (CLASSTYPE_CONSTRUCTORS (t)); iter; ++iter)
+ if (copy_fn_p (*iter) && !DECL_DELETED_FN (*iter))
+ return true;
+ return false;
+}
+
/* If T, a class, has a user-provided copy constructor, copy assignment
operator, or destructor, returns that function. Otherwise, null. */