[Bug c++/124731] New: [coroutines] Temporaries from await-expressions are destroyed prematurely in aggregate initialization

ddvamp007 at gmail dot com gcc-bugzilla@gcc.gnu.org
Tue Mar 31 12:06:18 GMT 2026


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

            Bug ID: 124731
           Summary: [coroutines] Temporaries from await-expressions are
                    destroyed prematurely in aggregate initialization
           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/1Px9sYhb1

When an await-expression appears in aggregate initialization, the materialized
awaiters are destroyed at the end of the designated-initializer-clause rather
than at the end of the full-expression.

#include <coroutine>
#include <iostream>

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) { return false; }
  auto await_resume() {
    std::cout << "resume" << std::endl;
    return 0;
  }

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

struct A {
  int a;
  int b;
};

Tag Coroutine() {
  std::cout << "[check]" << std::endl;
  A a1 = {.a = Awaiter{}.await_resume(),
          .b = Awaiter{}.await_resume()};

  std::cout << "\n[co_await]" << std::endl;
  A a2 = {.a = co_await Awaiter{},
          .b = co_await Awaiter{}};
}

int main() {
  Coroutine();
}

--std=c++2c -O0 -pedantic -Wall -Wextra

Output:
[check]
resume
resume
~Awaiter
~Awaiter

[co_await]
resume
~Awaiter
resume
~Awaiter


More information about the Gcc-bugs mailing list