]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c++, coroutines: Make the resume index consistent for debug.
authorIain Sandoe <iain@sandoe.co.uk>
Thu, 3 Oct 2024 08:02:59 +0000 (09:02 +0100)
committerIain Sandoe <iain@sandoe.co.uk>
Sun, 15 Dec 2024 17:04:55 +0000 (17:04 +0000)
At present, we only update the resume index when we actually are
at the stage that the coroutine is considered suspended. This is
on the basis that it is UB to resume or destroy a coroutines that
is not suspended (and therefore we never need to access this value
otherwise).  However, it is possible that someone could set a debug
breakpoint on the resume which can be reached without suspending
if await_ready() returns true.  In that case, the debugger would
read an incorrect resume index.  Fixed by moving the update to
just before the test for ready.

gcc/cp/ChangeLog:

* coroutines.cc (expand_one_await_expression): Update the
resume index before checking if the coroutine is ready.

Signed-off-by: Iain Sandoe <iain@sandoe.co.uk>
gcc/cp/coroutines.cc

index 9214dfcc53efccd5b166ee1994580aef2284ab9f..c286af7bd0769953a818e5a63eb26eb249a23d53 100644 (file)
@@ -2033,6 +2033,12 @@ expand_one_await_expression (tree *expr, tree *await_expr, void *d)
 
   /* Use the await_ready() call to test if we need to suspend.  */
   tree ready_cond = TREE_VEC_ELT (awaiter_calls, 0); /* await_ready().  */
+
+  /* We will resume (or continue) at the following index.  */
+  tree resume_idx = build_int_cst (short_unsigned_type_node, data->index);
+  tree r = cp_build_init_expr (data->resume_idx, resume_idx);
+  finish_expr_stmt (r);
+
   /* Convert to bool, if necessary.  */
   if (TREE_CODE (TREE_TYPE (ready_cond)) != BOOLEAN_TYPE)
     ready_cond = cp_convert (boolean_type_node, ready_cond,
@@ -2043,10 +2049,6 @@ expand_one_await_expression (tree *expr, tree *await_expr, void *d)
   ready_cond = invert_truthvalue_loc (loc, ready_cond);
   finish_if_stmt_cond (ready_cond, susp_if);
 
-  tree susp_idx = build_int_cst (short_unsigned_type_node, data->index);
-  tree r = cp_build_init_expr (data->resume_idx, susp_idx);
-  finish_expr_stmt (r);
-
   /* Find out what we have to do with the awaiter's suspend method.
      [expr.await]
      (5.1) If the result of await-ready is false, the coroutine is considered
@@ -2100,12 +2102,12 @@ expand_one_await_expression (tree *expr, tree *await_expr, void *d)
   tree cont = build_address (data->corocont);
   tree final_susp = build_int_cst (integer_type_node, is_final ? 1 : 0);
 
-  susp_idx = build_int_cst (integer_type_node, data->index);
+  resume_idx = build_int_cst (integer_type_node, data->index);
 
   tree sw = begin_switch_stmt ();
 
   r = build_call_expr_internal_loc (loc, IFN_CO_YIELD, integer_type_node, 5,
-                                   susp_idx, final_susp, r_l, d_l,
+                                   resume_idx, final_susp, r_l, d_l,
                                    data->coro_fp);
   finish_switch_cond (r, sw);
   finish_case_label (loc, integer_zero_node, NULL_TREE); /*  case 0: */