https://gcc.gnu.org/g:977fadd69776e2a8a6daca43e1c898bc4f87154d
commit r16-969-g977fadd69776e2a8a6daca43e1c898bc4f87154d Author: Iain Sandoe <i...@sandoe.co.uk> Date: Thu May 29 15:45:29 2025 +0100 c++, coroutines: Make a check more specific [PR109283]. 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> Diff: --- gcc/cp/coroutines.cc | 8 +++++--- gcc/testsuite/g++.dg/coroutines/pr109283.C | 23 +++++++++++++++++++++++ 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc index 64a0a344349e..5815a8cef2c4 100644 --- a/gcc/cp/coroutines.cc +++ b/gcc/cp/coroutines.cc @@ -2865,8 +2865,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; @@ -3116,7 +3116,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 000000000000..d73092b595e8 --- /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{}; +}