Date: Sun, 28 Sep 2025 13:55:33 +0300
The following code crashes on gcc 15.2, works on clang 21 and gcc 15.1
(godbolt: https://godbolt.org/z/njvqsb1c8) [1]
#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_neve
r(); }
std::suspend_never final_suspend() noexcept { return std::suspe
nd_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 destr
oy 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?
[1] https://godbolt.org/z/njvqsb1c8) https://godbolt.org/z/njvqsb1c8
(godbolt: https://godbolt.org/z/njvqsb1c8) [1]
#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_neve
r(); }
std::suspend_never final_suspend() noexcept { return std::suspe
nd_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 destr
oy 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?
[1] https://godbolt.org/z/njvqsb1c8) https://godbolt.org/z/njvqsb1c8
Received on 2025-09-28 10:55:41