https://gcc.gnu.org/bugzilla/show_bug.cgi?id=125289
Bug ID: 125289
Summary: Segmentation fault when awaitable derives from
abstract class
Product: gcc
Version: 16.1.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: rw at rolrolrol dot de
Target Milestone: ---
// c++ compiler frontend crashes when fed with code below
// see on godbolt: https://godbolt.org/z/GEc4PK973
#include <coroutine>
struct ReturnObject {
struct promise_type {
promise_type(){}
unsigned value_;
ReturnObject get_return_object() {
return ReturnObject {
.h_ = std::coroutine_handle<promise_type>::from_promise(*this)
};
}
std::suspend_never initial_suspend() { return {}; }
std::suspend_never final_suspend() noexcept { return {}; }
void unhandled_exception() {}
void return_value(int a){}
};
std::coroutine_handle<promise_type> h_;
operator std::coroutine_handle<promise_type>() const { return h_; }
};
template<typename PromiseType, typename AwaitReturn>
struct AbstractAwaitable
{
virtual bool await_ready() = 0;
virtual bool await_suspend(std::coroutine_handle<PromiseType> h) = 0;
virtual AwaitReturn await_resume() = 0;
};
template<typename PromiseType>
struct Awaitable : public AbstractAwaitable<PromiseType, void>
{
Awaitable(int &io_context)
: m_ioContext(io_context)
, m_timer(io_context)
{}
bool await_ready() override { return false; } // false means yes, do call
await_suspend
bool await_suspend(std::coroutine_handle<PromiseType> h) override
{
m_promise = &h.promise();
return false; // says no don't suspend coroutine after all
}
void await_resume() override { }
PromiseType *m_promise = nullptr;
int &m_ioContext;
int m_timer;
};
using AwaitableTimer = Awaitable<ReturnObject::promise_type>;
ReturnObject counter(AwaitableTimer &timer)
{
co_await timer;
co_return 5;
}
int main()
{
int io_context;
AwaitableTimer timer{io_context};
std::coroutine_handle<ReturnObject::promise_type> h = counter(timer);
io_context.run();
h.destroy();
}