[Bug c++/124720] New: [coroutines] Missing destructor call when an await-expression terminates by throwing an exception

ddvamp007 at gmail dot com gcc-bugzilla@gcc.gnu.org
Tue Mar 31 08:03:14 GMT 2026


https://gcc.gnu.org/bugzilla/show_bug.cgi?id=124720

            Bug ID: 124720
           Summary: [coroutines] Missing destructor call when an
                    await-expression terminates by throwing an exception
           Product: gcc
           Version: 16.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: ddvamp007 at gmail dot com
  Target Milestone: ---

https://godbolt.org/z/sdWdnf8af

If the evaluation of an await-expression terminates by throwing an exception,
the behavior differs depending on whether it is used in a declaration-statement
or an expression-statement.
When initialization of a variable is interrupted, the destructor of its
already-constructed initializer is not called.

#include <coroutine>
#include <iostream>

struct S {
  S() { std::cout << " S" << std::endl; }
  ~S() { std::cout << "~S" << std::endl; }
};

struct Tag {
  struct promise_type {
    Tag get_return_object() { return {}; }
    std::suspend_never initial_suspend() { return {}; }
    std::suspend_never final_suspend() noexcept { return {}; }
    void return_void() {}
    void unhandled_exception() {}
  };
};

struct Awaiter {
  auto await_ready() { return true; }
  auto await_suspend(auto) {}
  auto await_resume() { return S{}; }

  ~Awaiter() noexcept (false) { throw 0; }
};

Tag Coroutine() {
  try {
    std::cout << "[expression-statement]" << std::endl;
    co_await Awaiter{};
  } catch (...) {}

  std::cout << std::endl;

  try {
    std::cout << "[declaration-statement]" << std::endl;
    auto v = co_await Awaiter{};
  } catch (...) {}
}

int main() {
  Coroutine();
}


More information about the Gcc-bugs mailing list