https://gcc.gnu.org/bugzilla/show_bug.cgi?id=124584
--- Comment #13 from Jarrod Smith <jarrod.smith at ardentblue dot com> --- Additional data points and a standard-library-only testcase for this one (attached above, sb_coawait.cpp; returns 0 when correct). It covers two scenarios: A destroys the frame via coroutine_handle::destroy() while suspended at the binding's initializer (the tuple was never constructed, so nothing may be destroyed); B runs the coroutine to completion and checks every constructed object is destroyed exactly once. A second suspend point follows the binding in the same scope. gcc 15.3.0 -O0 A ok B: ctor=2 dtor=1 (destructor skipped at -O0 too, not only -O1+) gcc 15.3.0 -O2 A ok B: ctor=2 dtor=1 gcc 15.2.1 -O0 A: ctor=0 dtor=1 B ok (destructor runs on the never-constructed binding) gcc 15.2.1 -O2 A ok B: ctor=2 dtor=1 gcc 14.2.1, gcc 16.2.0, clang 20.1.8: all correct at -O0 and -O2 So on the 15 branch the lowering is wrong in both directions depending on version and level: 15.2.1 at -O0 destroys the binding when the frame is destroyed before the binding was constructed (on a real type this is a destructor call on uninitialized storage), while 15.3.0, and 15.x at -O1+, never destroy it. Two discriminators: -DNO_SECOND_SUSPEND (remove the later suspend point) makes 15.3.0 correct, and -DPLAIN_VARIABLE (auto r = co_await ...; auto& [n, t] = r;) is correct everywhere. At -O2, 15.x also warns sb_coawait.cpp:55:3: warning: '<anonymous>' may be used uninitialized [-Wmaybe-uninitialized] at the closing brace of the enclosing loop, which looks like the slot's destroy guard being read before it is written. Real-world shape where the -O0 variant bites: a boost::asio accept loop, auto [e, client] = co_await acceptor.async_accept(strand, as_tuple(use_awaitable)); with a backoff co_await in the error branch. Destroying the io_context with the accept pending runs ~basic_stream_socket on the never-constructed slot and segfaults on every SIGTERM; a loop whose binding holds a shared_ptr destroys the previous iteration's stale tuple a second time (ASan: heap-use-after-free). Boost-based repros available if useful. Since 16.2.0 is correct, is a backport of the fix to 15.4 planned? Happy to test a 15-branch patch against both the attached case and the asio cases. 15.2.1 above is Red Hat 15.2.1-7 (Fedora 42); 15.3.0 is the FSF release, x86_64-linux-gnu, plain "g++ -std=c++20 -O0|-O2 sb_coawait.cpp".
