https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94288

--- Comment #7 from CVS Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Iain D Sandoe <[email protected]>:

https://gcc.gnu.org/g:3dbc772128e944819b09e21021d4fcd5dc17f2d4

commit r10-7923-g3dbc772128e944819b09e21021d4fcd5dc17f2d4
Author: Iain Sandoe <[email protected]>
Date:   Thu Apr 23 16:59:00 2020 +0100

    coroutines: Fix handling of conditional statements [PR94288]

    Normally, when we find a statement containing an await expression
    this will be expanded to a statement list implementing the control
    flow implied.  The expansion process successively replaces each
    await expression in a statement with the result of its await_resume().

    In the case of conditional statements (if, while, do, switch) the
    expansion of the condition (or expression in the case of do-while)
    cannot take place 'inline', leading to the PR.

    The solution is to evaluate the expression separately, and to
    transform while and do-while loops into endless loops with a break
    on the required condition.

    In fixing this, I realised that I'd also made a thinko in the case
    of expanding truth-and/or-if expressions, where one arm of the
    expression might need to be short-circuited.  The mechanism for
    expanding via the tree walk will not work correctly in this case and
    we need to pre-expand any truth-and/or-if with an await expression
    on its conditionally-taken arm.  This applies to any statement with
    truth-and/or-if expressions, so can be handled generically.

    gcc/cp/ChangeLog:

    2020-04-23  Iain Sandoe  <[email protected]>

            PR c++/94288
            * coroutines.cc (await_statement_expander): Simplify cases.
            (struct susp_frame_data): Add fields for truth and/or if
            cases, rename one field.
            (analyze_expression_awaits): New.
            (expand_one_truth_if): New.
            (add_var_to_bind): New helper.
            (coro_build_add_if_not_cond_break): New helper.
            (await_statement_walker): Handle conditional expressions,
            handle expansion of truth-and/or-if cases.
            (bind_expr_find_in_subtree): New, checking-only.
            (coro_body_contains_bind_expr_p): New, checking-only.
            (morph_fn_to_coro): Ensure that we have a top level bind
            expression.

    gcc/testsuite/ChangeLog:

    2020-04-23  Iain Sandoe  <[email protected]>

            PR c++/94288
            * g++.dg/coroutines/torture/co-await-18-if-cond.C: New test.
            * g++.dg/coroutines/torture/co-await-19-while-cond.C: New test.
            * g++.dg/coroutines/torture/co-await-20-do-while-cond.C: New test.
            * g++.dg/coroutines/torture/co-await-21-switch-value.C: New test.
            * g++.dg/coroutines/torture/co-await-22-truth-and-of-if.C: New
test.
            * g++.dg/coroutines/torture/co-ret-16-simple-control-flow.C: New
test.

Reply via email to