[gcc r10-9514] coroutines : Adjust constraints on when to build ctors [PR98118].
Iain D Sandoe
iains@gcc.gnu.org
Mon Mar 22 22:04:12 GMT 2021
https://gcc.gnu.org/g:fad6d041ebf191eecdc98e162869c2f4a6eb245f
commit r10-9514-gfad6d041ebf191eecdc98e162869c2f4a6eb245f
Author: Iain Sandoe <iain@sandoe.co.uk>
Date: Wed Feb 17 15:13:57 2021 +0000
coroutines : Adjust constraints on when to build ctors [PR98118].
PR98118 shows that TYPE_NEEDS_CONSTRUCTING is necessary but not
sufficient. Use type_build_ctor_call() instead.
gcc/cp/ChangeLog:
PR c++/98118
* coroutines.cc (build_co_await): Use type_build_ctor_call()
to determine cases when a CTOR needs to be built.
(flatten_await_stmt): Likewise.
(morph_fn_to_coro): Likewise.
gcc/testsuite/ChangeLog:
PR c++/98118
* g++.dg/coroutines/pr98118.C: New test.
(cherry picked from commit 3d9577c254003f2d18185015b75ce6e3e4af9ca2)
Diff:
---
gcc/cp/coroutines.cc | 14 +++++++-------
gcc/testsuite/g++.dg/coroutines/pr98118.C | 29 +++++++++++++++++++++++++++++
2 files changed, 36 insertions(+), 7 deletions(-)
diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc
index 44f4946d7a3..582ee9489c5 100644
--- a/gcc/cp/coroutines.cc
+++ b/gcc/cp/coroutines.cc
@@ -950,7 +950,7 @@ build_co_await (location_t loc, tree a, suspend_point_kind suspend_kind)
e_proxy = o;
o = NULL_TREE; /* The var is already present. */
}
- else if (CLASS_TYPE_P (o_type) || TYPE_NEEDS_CONSTRUCTING (o_type))
+ else if (type_build_ctor_call (o_type))
{
e_proxy = get_awaitable_var (suspend_kind, o_type);
releasing_vec arg (make_tree_vector_single (rvalue (o)));
@@ -2985,7 +2985,7 @@ flatten_await_stmt (var_nest_node *n, hash_set<tree> *promoted,
gcc_checking_assert (!already_present);
tree inner = TREE_OPERAND (init, 1);
gcc_checking_assert (TREE_CODE (inner) != COND_EXPR);
- if (TYPE_NEEDS_CONSTRUCTING (var_type))
+ if (type_build_ctor_call (var_type))
{
releasing_vec p_in (make_tree_vector_single (init));
init = build_special_member_call (var, complete_ctor_identifier,
@@ -2997,9 +2997,9 @@ flatten_await_stmt (var_nest_node *n, hash_set<tree> *promoted,
var_nest_node *ins
= new var_nest_node (var, init, n->prev, n);
/* We have to replace the target expr... */
- proxy_replace pr = {TREE_OPERAND (t, 0), var};
*v.entry = var;
/* ... and any uses of its var. */
+ proxy_replace pr = {TREE_OPERAND (t, 0), var};
cp_walk_tree (&n->init, replace_proxy, &pr, NULL);
/* Compiler-generated temporaries can also have uses in following
arms of compound expressions, which will be listed in 'replace_in'
@@ -4709,7 +4709,7 @@ morph_fn_to_coro (tree orig, tree *resumer, tree *destroyer)
parm.frame_type, INIT_EXPR,
DECL_SOURCE_LOCATION (arg), arg,
DECL_ARG_TYPE (arg));
- else if (TYPE_NEEDS_CONSTRUCTING (parm.frame_type))
+ else if (type_build_ctor_call (parm.frame_type))
{
vec<tree, va_gc> *p_in;
if (CLASS_TYPE_P (parm.frame_type)
@@ -4767,7 +4767,7 @@ morph_fn_to_coro (tree orig, tree *resumer, tree *destroyer)
false, tf_warning_or_error);
tree promise_dtor = NULL_TREE;
- if (TYPE_NEEDS_CONSTRUCTING (promise_type))
+ if (type_build_ctor_call (promise_type))
{
/* Do a placement new constructor for the promise type (we never call
the new operator, just the constructor on the object in place in the
@@ -4848,7 +4848,7 @@ morph_fn_to_coro (tree orig, tree *resumer, tree *destroyer)
The expression promise.get_return_object() is used to initialize the
glvalue result or... (see below)
Construct the return result directly. */
- if (TYPE_NEEDS_CONSTRUCTING (gro_type))
+ if (type_build_ctor_call (gro_type))
{
vec<tree, va_gc> *arg = make_tree_vector_single (get_ro);
r = build_special_member_call (DECL_RESULT (orig),
@@ -4879,7 +4879,7 @@ morph_fn_to_coro (tree orig, tree *resumer, tree *destroyer)
DECL_CONTEXT (gro) = current_scope ();
add_decl_expr (gro);
gro_bind_vars = gro;
- if (TYPE_NEEDS_CONSTRUCTING (gro_type))
+ if (type_build_ctor_call (gro_type))
{
vec<tree, va_gc> *arg = make_tree_vector_single (get_ro);
r = build_special_member_call (gro, complete_ctor_identifier,
diff --git a/gcc/testsuite/g++.dg/coroutines/pr98118.C b/gcc/testsuite/g++.dg/coroutines/pr98118.C
new file mode 100644
index 00000000000..d09ffff2142
--- /dev/null
+++ b/gcc/testsuite/g++.dg/coroutines/pr98118.C
@@ -0,0 +1,29 @@
+namespace std {
+inline namespace __n4861 {
+template <typename _Result, typename> struct coroutine_traits : _Result {};
+template <typename = void> struct coroutine_handle;
+template <> struct coroutine_handle<> {};
+template <typename> struct coroutine_handle : coroutine_handle<> {};
+struct suspend_never {
+ bool await_ready() noexcept;
+ void await_suspend(coroutine_handle<>) noexcept;
+ void await_resume() noexcept;
+};
+} // namespace __n4861
+} // namespace std
+
+struct fire_and_forget {
+ struct promise_type {
+ fire_and_forget get_return_object();
+ std::suspend_never initial_suspend();
+ std::suspend_never final_suspend() noexcept;
+ void return_void();
+ void unhandled_exception();
+ };
+};
+
+struct bug {
+ ~bug();
+};
+
+fire_and_forget f(bug) { co_return; }
More information about the Gcc-cvs
mailing list