coroutines: Add cleanups, where required, to statements with captured references.
authorIain Sandoe <iain@sandoe.co.uk>
Wed, 8 Apr 2020 07:15:00 +0000 (08:15 +0100)
committerIain Sandoe <iain@sandoe.co.uk>
Thu, 9 Apr 2020 07:25:52 +0000 (08:25 +0100)
When we promote captured temporaries to local variables, we also
remove their initializers from the relevant call expression.  This
means that we should recompute the need for a cleanup expression
once the set of temporaries that remains becomes known.

gcc/cp/ChangeLog:

2020-04-08  Iain Sandoe  <iain@sandoe.co.uk>
    Jun Ma  <JunMa@linux.alibaba.com>

* coroutines.cc (maybe_promote_captured_temps): Add a
cleanup expression, if needed, to any call from which
we promoted temporaries captured by reference.

gcc/cp/ChangeLog
gcc/cp/coroutines.cc

index 50f1857a3ec44b5ed3a8a858c74ed6e52ab9da52..e63f30bf3c1d44dc498178a8fe50a82705f91044 100644 (file)
@@ -1,3 +1,10 @@
+2020-04-08  Iain Sandoe  <iain@sandoe.co.uk>
+           Jun Ma <JunMa@linux.alibaba.com>
+
+       * coroutines.cc (maybe_promote_captured_temps): Add a cleanup
+       expression, if needed, to any call from which we promoted
+       temporaries captured by reference.
+
 2020-04-08  Marek Polacek  <polacek@redhat.com>
 
        PR c++/94507 - ICE-on-invalid with lambda template.
index 983fa650b55e85f64ed301563dcc03b19a89572c..936be06c33629806a320b45c3676cb8f677b6dd1 100644 (file)
@@ -2798,11 +2798,13 @@ maybe_promote_captured_temps (tree *stmt, void *d)
       location_t sloc = EXPR_LOCATION (*stmt);
       tree aw_bind
        = build3_loc (sloc, BIND_EXPR, void_type_node, NULL, NULL, NULL);
-      tree aw_statement_current;
-      if (TREE_CODE (*stmt) == CLEANUP_POINT_EXPR)
-       aw_statement_current = TREE_OPERAND (*stmt, 0);
-      else
-       aw_statement_current = *stmt;
+
+      /* Any cleanup point expression might no longer be necessary, since we
+        are removing one or more temporaries.  */
+      tree aw_statement_current = *stmt;
+      if (TREE_CODE (aw_statement_current) == CLEANUP_POINT_EXPR)
+       aw_statement_current = TREE_OPERAND (aw_statement_current, 0);
+
       /* Collected the scope vars we need move the temps to regular. */
       tree aw_bind_body = push_stmt_list ();
       tree varlist = NULL_TREE;
@@ -2843,8 +2845,12 @@ maybe_promote_captured_temps (tree *stmt, void *d)
          /* Replace all instances of that temp in the original expr.  */
          cp_walk_tree (&aw_statement_current, replace_proxy, &pr, NULL);
        }
-      /* What's left should be the original statement with any temporaries
-        broken out.  */
+
+      /* What's left should be the original statement with any co_await
+        captured temporaries broken out.  Other temporaries might remain
+        so see if we need to wrap the revised statement in a cleanup.  */
+      aw_statement_current =
+       maybe_cleanup_point_expr_void (aw_statement_current);
       add_stmt (aw_statement_current);
       BIND_EXPR_BODY (aw_bind) = pop_stmt_list (aw_bind_body);
       awpts->captured_temps.empty ();