Hi
This patch does minor fix on changing context of label_decl from
original function to actor function which avoid assertion in gimplify pass.

Bootstrap and test on X86_64, is it OK?

Regards
JunMa

gcc/cp
2020-01-21  Jun Ma <ju...@linux.alibaba.com>

        * coroutines.cc (transform_await_wrapper): Set actor funcion as
        new context of label_decl.
        (build_actor_fn): Fill new field of await_xform_data.

gcc/testsuite
2020-01-21  Jun Ma <ju...@linux.alibaba.com>

        * g++.dg/coroutines/co-await-04-control-flow.C: Add label.
---
 gcc/cp/coroutines.cc                                  | 11 ++++++++---
 .../coroutines/torture/co-await-04-control-flow.C     |  2 ++
 2 files changed, 10 insertions(+), 3 deletions(-)

diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc
index bd3656562ec..2b6a154d28f 100644
--- a/gcc/cp/coroutines.cc
+++ b/gcc/cp/coroutines.cc
@@ -1562,6 +1562,7 @@ static hash_map<tree, suspend_point_info> *suspend_points;
 
 struct await_xform_data
 {
+  tree actor_fn;   /* Decl for context.  */
   tree actor_frame;
   tree promise_proxy;
   tree real_promise;
@@ -1643,12 +1644,16 @@ transform_await_expr (tree await_expr, await_xform_data 
*xform)
 static tree
 transform_await_wrapper (tree *stmt, int *do_subtree, void *d)
 {
+  /* Set actor function as new DECL_CONTEXT of label_decl.  */
+  struct await_xform_data *xform = (struct await_xform_data *) d;
+  if (TREE_CODE (*stmt) == LABEL_DECL
+      && DECL_CONTEXT (*stmt) != xform->actor_fn)
+    DECL_CONTEXT (*stmt) = xform->actor_fn;
+
   if (TREE_CODE (*stmt) != CO_AWAIT_EXPR && TREE_CODE (*stmt) != CO_YIELD_EXPR)
     return NULL_TREE;
 
   tree await_expr = *stmt;
-  await_xform_data *xform = (await_xform_data *) d;
-
   *stmt = transform_await_expr (await_expr, xform);
   if (*stmt == error_mark_node)
     *do_subtree = 0;
@@ -2005,7 +2010,7 @@ build_actor_fn (location_t loc, tree coro_frame_type, 
tree actor, tree fnbody,
      decide where to put things.  */
 
   await_xform_data xform
-    = {actor_frame, promise_proxy, ap, self_h_proxy, ash};
+    = {actor, actor_frame, promise_proxy, ap, self_h_proxy, ash};
 
   /* Get a reference to the initial suspend var in the frame.  */
   transform_await_expr (initial_await, &xform);
diff --git a/gcc/testsuite/g++.dg/coroutines/torture/co-await-04-control-flow.C 
b/gcc/testsuite/g++.dg/coroutines/torture/co-await-04-control-flow.C
index 9bc99e875d0..e8da2d2e2ad 100644
--- a/gcc/testsuite/g++.dg/coroutines/torture/co-await-04-control-flow.C
+++ b/gcc/testsuite/g++.dg/coroutines/torture/co-await-04-control-flow.C
@@ -16,9 +16,11 @@ coro1
 f ()
 {
   if (gX < 12) {
+L1:
     gX += y;
     gX += co_await 11;
   } else
+L2:
     gX += co_await 12;
     
   co_return gX;
-- 
2.19.1.3.ge56e4f7

Reply via email to