The following code crashes on gcc 15.2, works on clang 21 and gcc 15.1 (godbolt: https://godbolt.org/z/njvqsb1c8)



#include <coroutine>

struct a { };

struct my_coro {

int* x = new int(0);

struct promise_type {
int* xptr = nullptr;
void set(int x) { *xptr = x; }
my_coro get_return_object() {
auto c = my_coro();
xptr = c.x;
return c;
}
bool await_ready() { return false; }
void unhandled_exception() {}
std::suspend_never initial_suspend() { return std::suspend_never(); }
std::suspend_never final_suspend() noexcept { return std::suspend_never(); }
};

};

struct awaitable {
bool await_ready() { return false; }
void await_suspend(std::coroutine_handle<my_coro::promise_type> h) {
h.promise().set(7);
h.destroy();
}
void await_resume() {}
};

awaitable operator co_await(a v) {
return awaitable();
}

my_coro f() {
co_await a();
}

int main() {
auto c = f();
return *c.x;
}


The crux is awaitable::await_suspend() which is called from the off-ramp and destroys the coroutine. My reading of the Standard is that the coroutine is already suspended at this point and therefore I may destroy it.

I filed a gcc bug (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121961) but did not get a response.

What is the list's opinion? Is gcc wrong or am I?