> On 9 Dec 2024, at 19:34, Jason Merrill <ja...@redhat.com> wrote:
> 
> On 12/9/24 2:00 PM, Iain Sandoe wrote:
>>> On 9 Dec 2024, at 18:56, Jason Merrill <ja...@redhat.com> wrote:
>>> 
>>> On 11/29/24 8:47 AM, Iain Sandoe wrote:
>>>> Tested on x86_64-darwin, x86_64-linux,
>>>> OK for trunk?
>>>> thanks
>>>> Iain
>>>> --- 8< ---
>>>> At present, we only update the suspend 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.
>>> 
>>> Hmm, https://eel.is/c++draft/expr#await-5 reads to me like there's only a 
>>> suspend point if await_ready() returns false?
>> yes, exactly.
>> which would mean that we only updated the suspend index in that case (which 
>> is fine if the only observer of the index is the coroutines code).
>> This change is entirely to cater for the fact that a debugger can observe 
>> the coroutine in states other than those that can be reached from  resume() 
>> or destroy().
> 
> I guess I'm getting confused by the comment referring to a suspend point, 
> where actually we're dealing with the resume index, which is independent of 
> the suspend point?

Yes - although the coroutines code only ever inspects it after a suspension - a 
debugger could inspect it at any time and, logically, it should icrement as we 
pass each  “if (awaiter.await_ready())” independent of whether that results in 
a suspension.

> 
>>>> In that case, the debugger would
>>>> read an incorrect suspend index.  Fixed by moving the update to
>>>> just before the test for ready.
>>>> gcc/cp/ChangeLog:
>>>>    * coroutines.cc (expand_one_await_expression): Update the
>>>>    suspend point index before checking if the coroutine is
>>>>    ready.
>>>> Signed-off-by: Iain Sandoe <i...@sandoe.co.uk>
>>>> ---
>>>>  gcc/cp/coroutines.cc | 9 +++++----
>>>>  1 file changed, 5 insertions(+), 4 deletions(-)
>>>> diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc
>>>> index 3148559d208..b36730d793c 100644
>>>> --- a/gcc/cp/coroutines.cc
>>>> +++ b/gcc/cp/coroutines.cc
>>>> @@ -1964,6 +1964,11 @@ 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 are about to pass this suspend point.  */
>>>> +  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);
>>>> +
>>>>    /* Convert to bool, if necessary.  */
>>>>    if (TREE_CODE (TREE_TYPE (ready_cond)) != BOOLEAN_TYPE)
>>>>      ready_cond = cp_convert (boolean_type_node, ready_cond,
>>>> @@ -1974,10 +1979,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

Reply via email to