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.
Name |
Last commit
|
Last update |
---|---|---|
INSTALL | Loading commit data... | |
config | Loading commit data... | |
contrib | Loading commit data... | |
fixincludes | Loading commit data... | |
gcc | Loading commit data... | |
gnattools | Loading commit data... | |
gotools | Loading commit data... | |
include | Loading commit data... | |
intl | Loading commit data... | |
libada | Loading commit data... | |
libatomic | Loading commit data... | |
libbacktrace | Loading commit data... | |
libcc1 | Loading commit data... | |
libcpp | Loading commit data... | |
libdecnumber | Loading commit data... | |
libffi | Loading commit data... | |
libgcc | Loading commit data... | |
libgfortran | Loading commit data... | |
libgo | Loading commit data... | |
libgomp | Loading commit data... | |
libhsail-rt | Loading commit data... | |
libiberty | Loading commit data... | |
libitm | Loading commit data... | |
libobjc | Loading commit data... | |
liboffloadmic | Loading commit data... | |
libphobos | Loading commit data... | |
libquadmath | Loading commit data... | |
libsanitizer | Loading commit data... | |
libssp | Loading commit data... | |
libstdc++-v3 | Loading commit data... | |
libvtv | Loading commit data... | |
lto-plugin | Loading commit data... | |
maintainer-scripts | Loading commit data... | |
zlib | Loading commit data... | |
.dir-locals.el | Loading commit data... | |
.gitattributes | Loading commit data... | |
.gitignore | Loading commit data... | |
ABOUT-NLS | Loading commit data... | |
COPYING | Loading commit data... | |
COPYING.LIB | Loading commit data... | |
COPYING.RUNTIME | Loading commit data... | |
COPYING3 | Loading commit data... | |
COPYING3.LIB | Loading commit data... | |
ChangeLog | Loading commit data... | |
ChangeLog.jit | Loading commit data... | |
ChangeLog.tree-ssa | Loading commit data... | |
MAINTAINERS | Loading commit data... | |
Makefile.def | Loading commit data... | |
Makefile.in | Loading commit data... | |
Makefile.tpl | Loading commit data... | |
README | Loading commit data... | |
ar-lib | Loading commit data... | |
compile | Loading commit data... | |
config-ml.in | Loading commit data... | |
config.guess | Loading commit data... | |
config.rpath | Loading commit data... | |
config.sub | Loading commit data... | |
configure | Loading commit data... | |
configure.ac | Loading commit data... | |
depcomp | Loading commit data... | |
install-sh | Loading commit data... | |
libtool-ldflags | Loading commit data... | |
libtool.m4 | Loading commit data... | |
ltgcc.m4 | Loading commit data... | |
ltmain.sh | Loading commit data... | |
ltoptions.m4 | Loading commit data... | |
ltsugar.m4 | Loading commit data... | |
ltversion.m4 | Loading commit data... | |
lt~obsolete.m4 | Loading commit data... | |
missing | Loading commit data... | |
mkdep | Loading commit data... | |
mkinstalldirs | Loading commit data... | |
move-if-change | Loading commit data... | |
multilib.am | Loading commit data... | |
symlink-tree | Loading commit data... | |
test-driver | Loading commit data... | |
ylwrap | Loading commit data... |