Skip to content

Clang miscompilation producing double destroy coro local variable #109542

Open
@kelbon

Description

@kelbon

https://godbolt.org/z/KqqK1aqv6

struct inplace_generator_promise {
  using handle_type = std::coroutine_handle<inplace_generator_promise>;

  handle_type get_return_object() noexcept {
    return handle_type::from_promise(*this);
  }

  std::suspend_always yield_value(int) noexcept {
    return {};
  }

  static constexpr std::suspend_never initial_suspend() noexcept {
    return {};
  }

  std::suspend_always final_suspend() const noexcept {
    return {};
  }
  static constexpr void return_void() noexcept {
  }
  [[noreturn]] static void unhandled_exception() {
    throw;
  }
};

struct inplace_generator {
  using promise_type = inplace_generator_promise;
  using handle_type = std::coroutine_handle<promise_type>;

  handle_type handle;

  inplace_generator(std::coroutine_handle<promise_type> handle) noexcept : handle(handle) {
  }

  ~inplace_generator() {
    handle.destroy();
  }
};

struct dctor {
  dctor() {
    std::cout << "CREATED\n";
  }
  dctor(dctor&&) = delete;
  void operator=(dctor&&) = delete;
  ~dctor() {
    std::cout << "DELETED\n";
  }
};
inplace_generator starter(){
// double destroyed, firstly after throw, second in handle.destroy(), must not be destroyed in handle.destroy after it
    dctor d; 
    co_yield {};
    throw 0;
}

[[gnu::noinline]] void bug_reproducer() {
    starter().handle.resume();
}

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions