From: Iain Sandoe Date: Thu, 29 May 2025 14:45:29 +0000 (+0100) Subject: c++, coroutines: Make a check more specific [PR109283]. X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=977fadd69776e2a8a6daca43e1c898bc4f87154d;p=thirdparty%2Fgcc.git 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 --- diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc index 64a0a344349..5815a8cef2c 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 *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 + +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{}; +}