<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/67828>67828</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
[clang++] Crash when calling coroutine handle.destroy() in await suspend()
</td>
</tr>
<tr>
<th>Labels</th>
<td>
clang
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
FunMiles
</td>
</tr>
</table>
<pre>
This is a bump up of the issue [in ](https://github.com/llvm/llvm-project/issues/62335). The reason I am bring it back here is that the problem exists with the brew version of clang++ version 15 ( https://github.com/llvm/llvm-project/releases/download/llvmorg-15.0.7/llvm-project-15.0.7.src.tar.xz ).
So it does not seem to be an issue introduced by apple's LLVM fork.
@ChuanqiXu9 if you need me to run a local version of godbolt for you, I can certainly do it.
The code is
```cpp
#include <iostream>
#include <coroutine>
namespace crt = std;
struct Timer {
auto die_or_return(int t, bool destroy_handle=false)
{
struct awaiter {
bool await_ready() const noexcept { return false; }
void await_resume() const noexcept {}
/* https://en.cppreference.com/w/cpp/language/coroutines states:
* The coroutine is suspended (its coroutine state is populated with local variables and current suspension point).
* awaiter.await_suspend(handle) is called, where handle is the coroutine handle representing the current coroutine.
* Inside that function, the suspended coroutine state is observable via that handle,
* and it's this function's responsibility to schedule it to resume on some executor,
* or to be destroyed (returning false counts as scheduling)
*/
crt::coroutine_handle<> await_suspend(crt::coroutine_handle<> h) noexcept
{
auto n = next; // Making this variable thread_local is a workaround.
if (destroy_handle) {
h.destroy();
}
return n;
}
crt::coroutine_handle<> next;
bool destroy_handle;
};
return awaiter{ender, destroy_handle};
}
crt::coroutine_handle<> ender = crt::noop_coroutine();
};
inline static bool active{true};
struct [[nodiscard]] autodestruct_task {
struct promise_type {
~promise_type() { active = false; std::cout << "Dying" << std::endl; }
autodestruct_task get_return_object() noexcept
{
return autodestruct_task{crt::coroutine_handle<promise_type>::from_promise(*this)};
}
crt::suspend_always initial_suspend() noexcept { return {}; }
/// If the coroutine does not suspend at the end, its handle is automatically
/// destroyed.
crt::suspend_never final_suspend() noexcept {return {}; }
void return_void() noexcept {}
void unhandled_exception() noexcept { std::terminate(); }
};
crt::coroutine_handle<promise_type> handle;
explicit autodestruct_task(crt::coroutine_handle<promise_type> h) noexcept : handle(h) {}
};
autodestruct_task test_death(Timer &timer) {
co_await timer.die_or_return(0,true);
}
autodestruct_task end_task() {
std::cout << "Ending" << std::endl;
co_return;
}
int main() {
Timer timer;
timer.ender = end_task().handle;
auto tsk_handle = test_death(timer).handle;
while (active && !tsk_handle.done()) {
std::cout << "Resume" << std::endl;
tsk_handle();
}
}
```
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJykWEtv47oV_jX05uAaDhW_Fl7E9gQY4M6mHRTdGRR5bLGhSJWk4riL_vaCFPW0k-ngCoOJwcd5n-87EnNOXjTijiz3ZHmcsdoXxu5ea_1DKnSz3Ijb7mchHUgHDPK6rKCuwJzBFwjSuRqBLPdSA1keCd0U3leOZC-EvhL6epG-qPM5NyWhr0q9t3_-qKz5F3JP6GsU4Qh9XdEsWxK6ncPPAsEic0bDd2Al5FbqC0gPOeNvUKANisEXzEcjKmtyhSXgh3TewVX6Iq7nFq_wjtZJo4PBXDF9IXRP6L5bfloCoRv4bastKmQu2i3MVSvDRDpk7OWPp-V8MV9PbqXVubN87pmdf_wHgrdkcSSLl7-b4J8w6EAbDw6xBG8gR2A6RVlqb42oOQrIb8CqSiGhawd__vmPH3A29i2Jav4H8rw4FDXT_5b_rLcgz3AzNWhEASUG0bbWwEAZztQwSBcjcqN8EBhuEHqA78CZBo7WM6nVDUSwdaQsJIwbEdKSlleL5h-vqrRCM6m5qgUCyQ7SOG-RlST79mibG2tqLzV2-5qV6CrGEbj1QLIjOC9Ith9a4bytuYefskQLZJ32AABY7Q0IiSdjTxZ9bTWhG6k9-OBfbowCgc5bczsVTAuFJDuemXJI6LYN51BeeJI2dmXST_W1T5QcT5wsMnEjdEPoFrjRzoM2-MGx8uEqNFZBozTbA1kfR9kcPO9Gik6oq0v8VGonZHg9lvjLpOJRz3lVWTyjRc0xlf6V0NeQQPoaOqdmFwwLbW4cOM88RiEpRvQFmlJIR0KbutpVqAWK0GjSu8FuvB_OVKaqFfMomuZNRcmsZLlCB0wL4LW1qH0SF6u1MlL7voVg7OVLm5p5E6tkR4CoJsV0G1RzphSKUAbXCCzNZoMvQ0_SusXKokPtAyLFE8mu7uRn1nzXTgpsUOtca-6l0UFtENLH6EFwTO7QvodIwLtkjYDWhcMg8iFK0kdI8AGveyVrBxZdZbSTuVTS30L_O16gqIOrPsJBLCUwGpwpEfADee2N7VVM_TE2AVTqnCbBTR2H4MRSBm5q7R0w1-qTAYK3j2WGWrzb4NaHCsteutB0PXog2TeYZvdX54uQ-LZLHrRH18cRNHTEGo0fPnZlbBb4wd6a9EvXVSn4IrT4qandyJVXY9-YNbUWj2oCIIAyoZsJ8tDtwIZinnabHu8AbyrpYaeHJ-GK7m8-PPqroKUAfIJwU-ycnAsax0g9sS41KlnvQxOEmpuKHEgYudsv_cqDKDkmszupjalOPdWMI3xvtNSq7UvJE7RzL9-RrPfe1nh_I1FEnKz22gjpOLMizEnLYyyv6GXN_ckz9zamkHS3sqaUDk_-VuE9x_x3uJ1oILBJY1f0tmOUyJdNgOrAoAeSHYBQerzFlqTtUncOtVAjKmq13lt-QZ949WTyZkLafN5mD6myLYWpbLLef5XaUQCyb825szXlKe1ES15Cq4bsDuvoE4rttCVIOTF1ZTcHUksvmRogzdDDIYkn5v2cxRsYCUjy_TyhmX4CbNRAmnGjxgME_uwZKgSrDNXIlLp9pqKD5xaE7hzU-I4WzlJ_6d3_61wcT1IxhN8PRH11s9aNf-LUnI8Edh_qrko92lJq5vv-HRfsA_D5jXqCCaT1cvGjUpJL_6Biv-agOw1j37KXjtw3RUsG43jdu3TfkR6dPwlkviB0kyZiuvLhx5hhuDlF-IW4N58OyQtCDxHcJtD4pfJQVCkSY2UR1x7D0Dctvsah3t5k3CfmhLG-ZFI_Ut4EoonCkE8a33uKGDswf8BrcTjw7i3lNd4axbwN9d3layHDebppQZquCF0BoU-9uLkwHSFNffgqiH9L7wO_CmJ6eoUPxos-rN2P9qVuJnaZ2GZbNsPd02q7WiyeKV3Oit1ysxZrunyiDDGnOWerzZbz5bPA9RM7r5czuaMLmi22dPu0elotV_Nsma2oeMLlWojtZrMlzwssmVTz8OY8N_Yyiy-_u9V6QzczxXJULn6qoDS9zlOyPM7sLr5p5_XFkeeFks67XoKXXsXvG4MPAIGBD5a5Ioz9Or4FhJFuOu-Pxy-QaVaBEUzOaqt2f-G7R3DtfwEAAP__C3BSlg">