-
- Downloads
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 <iain@sandoe.co.uk> 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 <iain@sandoe.co.uk> 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.
Showing
- gcc/cp/ChangeLog 17 additions, 0 deletionsgcc/cp/ChangeLog
- gcc/cp/coroutines.cc 423 additions, 10 deletionsgcc/cp/coroutines.cc
- gcc/testsuite/ChangeLog 10 additions, 0 deletionsgcc/testsuite/ChangeLog
- gcc/testsuite/g++.dg/coroutines/torture/co-await-18-if-cond.C 85 additions, 0 deletions...testsuite/g++.dg/coroutines/torture/co-await-18-if-cond.C
- gcc/testsuite/g++.dg/coroutines/torture/co-await-19-while-cond.C 68 additions, 0 deletions...tsuite/g++.dg/coroutines/torture/co-await-19-while-cond.C
- gcc/testsuite/g++.dg/coroutines/torture/co-await-20-do-while-cond.C 68 additions, 0 deletions...ite/g++.dg/coroutines/torture/co-await-20-do-while-cond.C
- gcc/testsuite/g++.dg/coroutines/torture/co-await-21-switch-value.C 63 additions, 0 deletions...uite/g++.dg/coroutines/torture/co-await-21-switch-value.C
- gcc/testsuite/g++.dg/coroutines/torture/co-await-22-truth-and-of-if.C 81 additions, 0 deletions...e/g++.dg/coroutines/torture/co-await-22-truth-and-of-if.C
- gcc/testsuite/g++.dg/coroutines/torture/co-ret-16-simple-control-flow.C 49 additions, 0 deletions...g++.dg/coroutines/torture/co-ret-16-simple-control-flow.C
Loading
Please register or sign in to comment