aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIain Sandoe <iain@sandoe.co.uk>2020-06-09 19:17:14 +0100
committerIain Sandoe <iain@sandoe.co.uk>2020-06-09 20:52:34 +0100
commit006f28aefeb3be575239beddc7febe56dff463a2 (patch)
treece7205dac1694b22b3057ff47a863c35edb530d3
parent62963c60fc19d07615afe9d4f1b897b2f60801b2 (diff)
downloadgcc-006f28aefeb3be575239beddc7febe56dff463a2.zip
gcc-006f28aefeb3be575239beddc7febe56dff463a2.tar.gz
gcc-006f28aefeb3be575239beddc7febe56dff463a2.tar.bz2
coroutines: Ensure distinct DTOR trees [PR95137].
Part of the PR notes that there are UBSAN fails for the coroutines test suite. These are primarily related to the use of the same DTOR tree in the two edges from the await block. Fixed by building a new tree for each. gcc/cp/ChangeLog: PR c++/95137 * coroutines.cc (expand_one_await_expression): Build separate DTOR trees for the awaitable object on the destroy and resume paths.
-rw-r--r--gcc/cp/coroutines.cc22
1 files changed, 13 insertions, 9 deletions
diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc
index e86b3d4..3c8c70f 100644
--- a/gcc/cp/coroutines.cc
+++ b/gcc/cp/coroutines.cc
@@ -1488,19 +1488,13 @@ expand_one_await_expression (tree *stmt, tree *await_expr, void *d)
tree resume_label = create_named_label_with_ctx (loc, buf, actor);
tree empty_list = build_empty_stmt (loc);
- tree dtor = NULL_TREE;
tree await_type = TREE_TYPE (var);
- if (needs_dtor)
- dtor = build_special_member_call (var, complete_dtor_identifier, NULL,
- await_type, LOOKUP_NORMAL,
- tf_warning_or_error);
-
tree stmt_list = NULL;
tree t_expr = STRIP_NOPS (expr);
tree r;
tree *await_init = NULL;
if (t_expr == var)
- dtor = NULL_TREE;
+ needs_dtor = false;
else
{
/* Initialize the var from the provided 'o' expression. */
@@ -1615,7 +1609,12 @@ expand_one_await_expression (tree *stmt, tree *await_expr, void *d)
destroy_label = build_stmt (loc, LABEL_EXPR, destroy_label);
append_to_statement_list (destroy_label, &body_list);
if (needs_dtor)
- append_to_statement_list (dtor, &body_list);
+ {
+ tree dtor = build_special_member_call (var, complete_dtor_identifier,
+ NULL, await_type, LOOKUP_NORMAL,
+ tf_warning_or_error);
+ append_to_statement_list (dtor, &body_list);
+ }
r = build1_loc (loc, GOTO_EXPR, void_type_node, data->cleanup);
append_to_statement_list (r, &body_list);
@@ -1650,7 +1649,12 @@ expand_one_await_expression (tree *stmt, tree *await_expr, void *d)
/* Get a pointer to the revised statment. */
tree *revised = tsi_stmt_ptr (tsi_last (stmt_list));
if (needs_dtor)
- append_to_statement_list (dtor, &stmt_list);
+ {
+ tree dtor = build_special_member_call (var, complete_dtor_identifier,
+ NULL, await_type, LOOKUP_NORMAL,
+ tf_warning_or_error);
+ append_to_statement_list (dtor, &stmt_list);
+ }
data->index += 2;
/* Replace the original statement with the expansion. */