Tested on x86_64-darwin, powerpc64le-linux; I'd like to minimize effort on this code, since I expect that we will need some changes to deal with open BZs. This fixes an ICE tho, OK for trunk? thanks Iain
--- 8< --- The check was intended to assert that we had visited contained ternary expressions with embedded co_awaits, but had been made too general - and therefore was ICEing on code that was actually OK. Fixed by checking specifically that no co_awaits embedded. PR c++/109283 gcc/cp/ChangeLog: * coroutines.cc (find_any_await): Only save the statement pointer if the caller passes a place for it. (flatten_await_stmt): When checking that ternary expressions have been handled, also check that they contain a co_await. gcc/testsuite/ChangeLog: * g++.dg/coroutines/pr109283.C: New test. Signed-off-by: Iain Sandoe <i...@sandoe.co.uk> --- gcc/cp/coroutines.cc | 8 +++++--- gcc/testsuite/g++.dg/coroutines/pr109283.C | 23 ++++++++++++++++++++++ 2 files changed, 28 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/g++.dg/coroutines/pr109283.C diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc index c1c10782906..dbb21a2ff77 100644 --- a/gcc/cp/coroutines.cc +++ b/gcc/cp/coroutines.cc @@ -2878,8 +2878,8 @@ find_any_await (tree *stmt, int *dosub, void *d) if (TREE_CODE (*stmt) == CO_AWAIT_EXPR) { *dosub = 0; /* We don't need to consider this any further. */ - tree **p = (tree **) d; - *p = stmt; + if (d) + *(tree **)d = stmt; return *stmt; } return NULL_TREE; @@ -3129,7 +3129,9 @@ flatten_await_stmt (var_nest_node *n, hash_set<tree> *promoted, bool already_present = promoted->add (var); gcc_checking_assert (!already_present); tree inner = TARGET_EXPR_INITIAL (init); - gcc_checking_assert (TREE_CODE (inner) != COND_EXPR); + gcc_checking_assert + (TREE_CODE (inner) != COND_EXPR + || !cp_walk_tree (&inner, find_any_await, nullptr, nullptr)); init = cp_build_modify_expr (input_location, var, INIT_EXPR, init, tf_warning_or_error); /* Simplify for the case that we have an init containing the temp diff --git a/gcc/testsuite/g++.dg/coroutines/pr109283.C b/gcc/testsuite/g++.dg/coroutines/pr109283.C new file mode 100644 index 00000000000..d73092b595e --- /dev/null +++ b/gcc/testsuite/g++.dg/coroutines/pr109283.C @@ -0,0 +1,23 @@ +// PR 109283. +// This used to ICE from a check set too widely. +#include <coroutine> + +struct foo +{ ~foo(); }; + +struct task +{ + struct promise_type + { + std::suspend_never initial_suspend(); + std::suspend_never final_suspend() noexcept; + std::suspend_never yield_value(foo); + void return_void(); + void unhandled_exception(); + task get_return_object(); + }; +}; + +task source(int b) { + co_yield b ? foo{} : foo{}; +} -- 2.39.2 (Apple Git-143)