https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121978
Mathias Stearn <redbeard0531 at gmail dot com> changed:
What |Removed |Added
----------------------------------------------------------------------------
See Also| |https://gcc.gnu.org/bugzill
| |a/show_bug.cgi?id=101244,
| |https://gcc.gnu.org/bugzill
| |a/show_bug.cgi?id=102217,
| |https://gcc.gnu.org/bugzill
| |a/show_bug.cgi?id=101027,
| |https://gcc.gnu.org/bugzill
| |a/show_bug.cgi?id=114728
--- Comment #3 from Mathias Stearn <redbeard0531 at gmail dot com> ---
If it helps anyone debug, here is the failing assertion:
https://github.com/gcc-mirror/gcc/blob/6e624833cbe0a7479564fbe3294e10c9d4746a2e/gcc/cp/coroutines.cc#L3252-L3254
gcc_checking_assert
(TREE_CODE (inner) != COND_EXPR
|| !cp_walk_tree (&inner, find_any_await, nullptr, nullptr));
Based on some of the surrounding code/comments and some related bugs that I'm
adding to See Also, I think GCC has a general problem with conditionally
evaluated suspension points that are tucked into subexpressions. That is, when
EXPR is something like (b ? co_await blah : 1) or (b && co_await blah), it is
fine with:
auto out = EXPR;
co_return out;
but:
co_return EXPR;
and even:
auto identity(auto x) { return x; }
auto out = identity(EXPR);
co_return out;
cause it to go off the rails and evaluate code in the non-taken path. Compare
https://godbolt.org/z/aoM1bsf7T (good: no identity call) vs
https://godbolt.org/z/T5MnoTodb (bad: with identity call). It seems like the
code that is responsible for handling the conditional suspention is making some
assumptions that don't actually hold. I'm not a compiler engineer and haven't
fully read that code, but there are a lot of comments in that function
indicating that it is looking for very specific patterns and those are the only
ones it expects to need to handle. Hopefully there is a simple (or at least
straightforward) solution here that can squash the whole category of bugs here
by making that logic more generic.