Open
Description
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();
}