https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97452

Mathias Stearn <redbeard0531 at gmail dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |redbeard0531 at gmail dot com

--- Comment #15 from Mathias Stearn <redbeard0531 at gmail dot com> ---
I'm not 100% sure that the code as written is incorrectly handled since the two
operands of + are unsequenced. https://eel.is/c++draft/intro.execution#12 is a
bit ambiguous unfortunately. As written, I _think_ it says that the operations
of an await-expression are indivisible, however it then starts talking about
what happens when you resume a coroutine and says that the indivisibility only
applies from the prior to the next suspension point. It doesn't say if it is
talking about the suspension of the current coroutine function that contains
the await-expression or the function potentially being resumed. It seems to
only make sense if it is talking about the function being resumed, but then
that makes me question whether the indivisibility of the await-expression is
actually meant to apply to its decomposition in the caller, or just the
operations in the resumed coroutine.

Setting that aside, the await-expressions _should_ definitely not be
interleaved where they are either indeterminitely sequenced or fully sequenced.
However, either gcc has a bug where await expressions are indeterminitely
sequenced, or it has a more widespread bug where function arguments are still
considered unsequenced, even though they became indeterminately sequenced in
C++17 via wg21.link/p0145.

I modified the minimal repo to have each case: https://godbolt.org/z/PM11PrafE

task example() {
#define CASE 1
#if CASE == 1 // unsequenced
  int b = co_await z + co_await z;
#elif CASE == 2 // indeterminiately sequenced
  int b = add(co_await z, co_await z);
#elif CASE == 3 // fully sequenced
  int b = co_await z << co_await z;
#endif
}

GCC does the right thing in case 3, but seems to treat case 1 and 2 the same
and interleaves the decompositions of the await-expression. Regardless of
whether case 1 is a bug, case 2 definitely is!

Reply via email to