Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Simple coroutine leaking with GCC 10

Tags:

c++

gcc

c++20

Consider the following simple coroutine, which tracks its construction and destruction:

#include <coroutine>
#include <iostream>

struct simple {
  static inline int x = 0;
  int id = 0;
  simple() : id{ x++ } { std::cout << id << " constructed\n"; }
  simple(simple&&) : id{ x++ } { std::cout << id << " move constructed\n"; }
  ~simple() { std::cout << id << " destructed\n"; }

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

simple f() { co_return; }

int main() {
  f();
}

When compiling with GCC 10.1, the output is:

0 constructed
1 move constructed
1 destructed

—notably, id 0 is never destructed. This is true even with GCC trunk.

Is there something I've done wrong here, some hidden UB or the like? Or is GCC at fault here?

As a comparison, I tried using Clang's experimental coroutine support, and got

0 constructed
0 destructed

which is closer to what I was expecting. I also get this "correct" output even in GCC if I comment out the move constructor in the coroutine object.

Live example: https://godbolt.org/z/UQVURi

like image 801
N. Shead Avatar asked Jun 01 '20 04:06

N. Shead


1 Answers

As Oliv mentioned, it appears this is just a bug with GCC's experimental coroutine support. A ticket has been raised here.

like image 82
N. Shead Avatar answered Oct 20 '22 12:10

N. Shead