<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">