https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103953
Bug ID: 103953 Summary: Leak of coroutine return object Product: gcc Version: 12.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: fchelnokov at gmail dot com Target Milestone: --- The following code: ``` #include <coroutine> #include <iostream> struct task { struct promise_type; using handle_type = std::coroutine_handle<promise_type>; task(handle_type h) : handle(h) { std::cout << "task ctor " << this << '\n'; } task(const task & t) : handle(t.handle) { std::cout << "task copy ctor " << this << '\n'; } task(task && t) : handle(std::move(t.handle)) { std::cout << "task move ctor " << this << '\n'; } ~task() { std::cout << "task dtor " << this << '\n'; } struct promise_type { auto get_return_object() { return task{handle_type::from_promise(*this)}; } auto initial_suspend() { return std::suspend_always {}; } auto unhandled_exception() {} auto final_suspend() noexcept { return std::suspend_always{}; } void return_void() {} }; handle_type handle; void await_resume() { handle.resume(); } auto await_suspend(handle_type) { return handle; } auto await_ready() { return false; } }; int main() { task coroutine_A = []() ->task { co_return; }(); task coroutine_B = [&coroutine_A]() ->task { co_await coroutine_A; }(); coroutine_B.handle.resume(); } ``` prints ``` task ctor 0x7ffc85d3d598 task ctor 0x7ffc85d3d590 task copy ctor 0x194af30 task dtor 0x7ffc85d3d590 task dtor 0x7ffc85d3d598 ``` meaning that one instance of task was not destructed (0x194af30). Demo: https://gcc.godbolt.org/z/6vnoMGvxo Related discussion: https://stackoverflow.com/q/70632655/7325599