<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/105595>105595</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            [clang][coroutines] Run-time crash with optimization when using coroutine with `co_await`
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            clang
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          dgg5503
      </td>
    </tr>
</table>

<pre>
    ## Summary
Starting with Clang 17 at commit 54225c457a336b1609c6d064b2b606a9238a28b9, attempting to execute the provided reduced programs compiled with `clang` using `-O2` results in a crash at runtime.

Specifically, the crash occurs in the function `void bx::await_suspend` when the result of `q`, a null pointer, is dereferenced to call `x()`.

I have confirmed that both reproducers run without triggering sanitizers in my environment (address, memory, undefined, etc.).

## Reproducers
**`reduced-Version-A.cpp`** -- https://godbolt.org/z/bxEf8Tfc6
```c++
#include <coroutine>
#include <memory>

struct br;
struct bs {
 bs(std::coroutine_handle<br>);
  int x() { return bt; }
  void bu() { bt = 0; }
  void t() { bv.resume(); }
  std::coroutine_handle<br> bv;
  int bt;
};
struct bw {
  using promise_type = br;
 bw(std::coroutine_handle<promise_type> h) : v(make_shared<bs>(h)) {}
 void t() { v->t(); }
  std::shared_ptr<bs> r() { return v; }
 std::shared_ptr<bs> v;
};
struct bx {
  int await_ready() { return 0; }
  void await_resume() {}
  void await_suspend(std::coroutine_handle<br>);
  bw by;
};
struct br {
  auto initial_suspend() { return std::suspend_always(); }
  auto final_suspend() noexcept { return std::suspend_always(); }
  auto get_return_object() {
    return std::coroutine_handle<br>::from_promise(*this);
  }
  void unhandled_exception() {}
  auto await_transform(bw h) { return bx(h); }
  void return_void() {}
  void u(bs *h) { v = h; }
  bs *r() { return v; }
  bs *v;
};
void bx::await_suspend(std::coroutine_handle<br> h) {
  auto bi = h.promise();
  auto q = bi.r();
  auto s = by.r();
  if (q->x())
 s->bu();
  by.t();
}
bs::bs(std::coroutine_handle<br> h) {
 bt = 0;
  bv = h;
  auto &bz = h.promise();
  bz.u(this);
}
bw ca() {
  fprintf(stderr, "ca (co_return) called\n");
 co_return;
}
bw cb() {
  fprintf(stderr, "cb (co_await) called\n");
  co_await ca();
}
bw cc = cb();
int main() {
 bw cd(cc);
  cd.t();
}
```

Here is the same reproducer reduced including headers from glibc 2.35 / glibcxx 3.4.30
**`reduced-Version-B.cpp`** -- https://godbolt.org/z/fsaKof3EE
```c++
namespace std {
template <int a> struct b {
  struct c {
    int d[a];
  };
};
inline namespace {
template <typename e> struct coroutine_traits : e {};
template <typename = void> struct coroutine_handle;
template <> struct coroutine_handle<> {};
template <typename f> struct coroutine_handle {
  static coroutine_handle g(f &h) {
 coroutine_handle i;
    i.k = __builtin_coro_promise(&h, 0, 1);
 return i;
  }
  static coroutine_handle from_address(void *h) {
 coroutine_handle i;
    i.k = h;
    return i;
  }
 coroutine_handle<> j;
  operator coroutine_handle<>() { return j; }
 void l() { __builtin_coro_resume(k); }
  f &m() {
    void *aa = __builtin_coro_promise(k, 0, 0);
    return *static_cast<f *>(aa);
 }
  void *k;
};
struct ab {
  int await_ready() noexcept { return 0; }
  void await_suspend(coroutine_handle<>) noexcept {}
  void await_resume() noexcept {}
};
} // namespace
template <typename, typename> struct n;
template <template <typename...> class w, typename y, typename ac,
          typename... ad>
struct n<w<ac, ad...>, y> {
 using c = w<y>;
};
} // namespace std
void *operator new(unsigned long, void *);
template <typename ac, typename... ae> void af(ac *h, ae... o) {
  new (h) ac(o...);
}
template <typename ac> struct ag {
 ac *ah(int) { return static_cast<ac *>(operator new(sizeof(ac))); }
};
namespace std {
template <typename ai, typename y> using aj = n<ai, y>::c;
template <typename> struct p;
template <typename ac> struct p<ag<ac>> {
  using ak = ag<ac>;
  using al = ac;
  using am = ac *;
  using an = int;
  static am ah(ak h, an) { return h.ah(0); }
  template <typename y, typename... ae> static void ao(ak, y o, ae... ap) {
    af(o, ap...);
  }
};
} // namespace std
namespace std {
template <typename ai> struct aq {
  using am = p<ai>::am;
 using al = p<ai>::al;
  aq(ai, am o) : ar(o) {}
  al *as() { return ar; }
  am ar;
};
template <typename ai> aq<ai> at(ai h) { return {h, p<ai>::ah(h, 0)}; }
} // namespace std
template <typename ac> struct au {
  std::b<sizeof(ac)>::c av;
  ac *ar() {
    void *j = &av;
 return static_cast<ac *>(j);
  }
};
namespace std {
template <typename> struct aw;
template <typename ac> struct ax {
  ax(ac) {}
};
template <typename ai> struct ay {
  ai az;
};
template <typename ac, typename ai> struct ba {
  struct bb : ax<ai> {
 au<ac> av;
  };
  using bc = aj<ai, ba>;
  template <typename... ae> ba(ai h, ae... o) : bd(h) {
    p<ai>::ao(h, ar(), o...);
  }
  ac *ar() { return bd.av.ar(); }
  bb bd;
};
struct be {
  template <typename ac, typename ai, typename... ae>
  be(ac *&h, ay<ai> o, ae... ap) {
    typedef ba<ac, ai> bf;
    typename bf::bc bg;
    auto bh = at(bg);
    bf *bj = bh.as();
    auto bk = new (bj) bf(o.az, ap...);
    h = bk->ar();
  }
};
template <typename ac> struct z {
  using bl = ac;
  bl *operator->() {
    bl *bm = static_cast<aw<ac> *>(this)->as();
    return bm;
  }
};
template <typename ac> struct aw : z<ac> {
  using bl = ac;
  bl *as() { return ar; }
  template <typename ai, typename... ae> aw(ai h, ae... o) : bn(ar, h, o...) {}
  bl *ar;
  be bn;
};
template <typename ac> struct bo : aw<ac> {
  template <typename ai, typename... ae> bo(ai h, ae... o) : aw<ac>(h, o...) {}
};
template <typename ac, typename ai, typename... ae> bo<ac> bp(ai h, ae... o) {
  return bo<ac>(ay<ai>{h}, o...);
}
template <typename ac, typename... ae> bo<ac> bq(ae... h) {
  return bp<ac>(ag<int>(), h...);
}
} // namespace std
struct br;
struct bs {
  bs(std::coroutine_handle<br>);
  int x() { return bt; }
  void bu() { bt = 0; }
  void t() { bv.l(); }
 std::coroutine_handle<br> bv;
  int bt;
};
struct bw {
  using promise_type = br;
  bw(std::coroutine_handle<promise_type> h) : v(bq<bs>(h)) {}
  void t() { v->t(); }
  std::bo<bs> r() { return v; }
  std::bo<bs> v;
};
struct bx {
  int await_ready() { return 0; }
  void await_resume() {}
  void await_suspend(std::coroutine_handle<br>);
  bw by;
};
struct br {
  auto initial_suspend() { return std::ab(); }
  auto final_suspend() noexcept { return std::ab(); }
  auto get_return_object() { return std::coroutine_handle<br>::g(*this); }
  void unhandled_exception() {}
 auto await_transform(bw h) { return bx(h); }
  void return_void() {}
 void u(bs *h) { v = h; }
  bs *r() { return v; }
  bs *v;
};

// When reduced including headers, the following is required under
// clang -O2 @ 54225c457a336b1609c6d064b2b606a9238a28b9, otherwise this
// entire function is optimized out which masks the problem since the crash
// occurs at `q->x()` (q is nullptr).
#pragma clang optimize off
void bx::await_suspend(std::coroutine_handle<br> h) {
  auto bi = h.m();
  auto q = bi.r();
  auto s = by.r();
  if (q->x())
 s->bu();
  by.t();
}
#pragma clang optimize on

bs::bs(std::coroutine_handle<br> h) {
  bt = 0;
  bv = h;
 auto &bz = h.m();
  bz.u(this);
}
bw ca() { co_return; }
bw cb() { co_await ca(); }
bw cc = cb();
int main() {
  bw cd(cc);
 cd.t();
}
```

## Reproduction Steps
### Latest Clang -- Crashes
```bash
$ clang++ --version
clang version 20.0.0git (https://github.com/llvm/llvm-project.git 381a803da253b75c8b7b10bb732e9e90925185e8)
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: <redacted>
$ clang++ -O0 -std=c++20 reduced-Version-A.cpp -o reduced-Version-A.out
$ ./reduced-Version-A.out
cb (co_await) called
ca (co_return) called
$ clang++ -O2 -std=c++20 reduced-Version-A.cpp -o reduced-Version-A.out
$ ./reduced-Version-A.out
cb (co_await) called
Segmentation fault (core dumped)
$ clang++ -O0 -std=c++20 reduced-Version-B.cpp -o reduced-Version-B.out
$ ./reduced-Version-B.out
$ clang++ -O2 -std=c++20 reduced-Version-B.cpp -o reduced-Version-B.out
$ ./reduced-Version-B.out
Segmentation fault (core dumped)
```

### Clang At Bisected Commit -- Crashes
```bash
$ clang++ --version
clang version 17.0.0 (https://github.com/llvm/llvm-project.git 54225c457a336b1609c6d064b2b606a9238a28b9)
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: <redacted>
$ clang++ -O0 -std=c++20 reduced-Version-A.cpp -o reduced-Version-A.out
$ ./reduced-Version-A.out
cb (co_await) called
ca (co_return) called
$ clang++ -O2 -std=c++20 reduced-Version-A.cpp -o reduced-Version-A.out
$ ./reduced-Version-A.out
cb (co_await) called
Segmentation fault (core dumped)
$ clang++ -O0 -std=c++20 reduced-Version-B.cpp -o reduced-Version-B.out
$ ./reduced-Version-B.out
$ clang++ -O2 -std=c++20 reduced-Version-B.cpp -o reduced-Version-B.out
$ ./reduced-Version-B.out
Segmentation fault (core dumped)
```

### Clang Before Bisected Commit -- Does not crash
```bash
$ clang++ --version
clang version 17.0.0 (https://github.com/llvm/llvm-project.git 32be3405f57f1e4d0ec0da943434113450583e89)
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: <redacted>
$ clang++ -O0 -std=c++20 reduced-Version-A.cpp -o reduced-Version-A.out
$ ./reduced-Version-A.out
cb (co_await) called
ca (co_return) called
$ clang++ -O2 -std=c++20 reduced-Version-A.cpp -o reduced-Version-A.out
$ ./reduced-Version-A.out
cb (co_await) called
ca (co_return) called
$ clang++ -O0 -std=c++20 reduced-Version-B.cpp -o reduced-Version-B.out
$ ./reduced-Version-B.out
$ clang++ -O2 -std=c++20 reduced-Version-B.cpp -o reduced-Version-B.out
$ ./reduced-Version-B.out
```

</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzsG1lv47j51zAvhAWZsnw85MFxEnTRAgvsLNpHg5Qoi4lEKiTlI7--IKnbsmPPbLtbdBbBrC1-_O6L-misFNtxSh9B-ATC5wdc6lTIx3i3C0M_eCAiPj0CFAAUwG9lnmN5Av4z8NffNJaa8R08MJ3CTYb5Dk4XEGsYiTxnGoYzhMJoFi5wEMzJdO6vonnsz2cEkbk_xysULDFakhVAG4i1pnlh0WkB6ZFGpaZQpxQWUuxZTGMoaVxGNDYPdhLnypApWEZjxwCY-5HhAcx9WCqDCMz9ya_IfJdUlZlWkHGIYSSxSg2bsuSa5dRz4lRCFTRiCYtwlp0MX4YDt0FEUSktCvMsKXmkmeCGyF6wGJIjCNYgWOMDZnqrSlVQHhvah5S6LY4JKBKz5wPMfSs35GWWwUIwrqk0T5iCMZU0oZJyI64W0HBjNh0BWgK0AnO_x_MvMMV7CiPBEyZzsyXFGhKhUyhpIYVRm1RGXKspUWqoJdvtqDRaUpgzzT6pky0_Qcr3TAqeU64hQEscx5IqZVjLaS6kVUvJY5owTmPzherIA2jV46lymN9a-vVz-zf3K2tO_kmlYoJP1l5UFFYpBgBOJjDVulBGqegVoNediInItCfkDqDXT4BeyfElWf6eRPMK89x3fxFAT-av5oPxKCtjCkGwiYQUpWacguBlbL0SsFm0_yoty0hDIkHw1H-iIFhUjyBRAC2Vjp0XNIS2KeZxRkGwMftfjPVqLBAyrmFlU4MJSqpLySHRIHiCYPFcwzkHKzuQREMQPEN_DFB34faecbucVp7TB_-SXUj2A3Ytb5V2Fs9nGjl0NFJFYSFFzhTd6lNBLdMdRUJy-EJr3d2GodRKFqzhHqBljt_pVqVY0thwrKyClwakkr-V9Uwz-wkIXvR1tTjU20LLGj2U5-ba97df272_qrxjV3lG2S6XSIrj0znZUdvXO1qT99XQhapz1N1uSw6QnK5KIruS4FILyEySwVmH6ECcVm0OYouzAz6pUQNZjAnjZ_i4oMeIFvqHEO-o0aDZuxXkjUYdr6nh4Bnyi5qzq4kU-bZyZYttrVOm-lodGqnkDlO8dTIxwUctanl2FtUSc5UImQO0JIcqVjp55VhHx4jnVBKbz5cdx6Qgk_XQusG9tzGdDlA6oK-DpQIcj4srdfUGn23E7ymKMMev17VG1wwW6sMlKubJ8XXl1k8j6ywxRfPDZJe6XKNVnRrM0zqPdwPq5OnBw0ZFRDkxb6svQ6E7daIh1lqsJxNAc_L5hXLIp2e4Hzpvy-wBRvg8XJJCMq4TJwCVts0BCEXYqCoSVbSZTabToTEINxwg1KPdgo1SJbdTJRVV61HXicIarBFrnHpk9VYz0cCYHJ5jxs94M3uME0fRgFx82RGa_qbbm_yNSmo6RtNfKpzTTsPX9MuuvzGlOKU4Nn2eSUdwlzESQeQFIQTo1X09HmHgzbzA_6JZe7q7WUsU_rtIgpeXa80axzlVBY6oyautuszJIMPadmi2LBpHr0tN1-LVs6ifqs2WGIRPGITPg3w7lnUYzxinsOVllA_TjxgQSDvMtFGpJWZa2UaF1ok0uIbG-I_NvWPY6hgfQXAV3q7eQj25gqavYKxZdA6yA2hp8t58kH7OAFnHABAy790Kvt2SkmWa8a3Z0CuUBuMG2qPStBcrVT1h4xX0EqO2EDcnmqWtMJ1qdh_bae_pVYYu2OatAywKKrEW8gLseSl965dSK0vWARtotWkK3887AGu7fKzPqTWE8XVLvTdm8vsprVEMQGtnlW2ElQbBxhBdO8kw7m0ath0Ard-v9ZuYfN05j7WGV1rottG4ZI4-yhsa8VHwQRaCLn-22edy0Nq3E_XnNnz5eKSPIPA8z-yLMqwUPHTRwVPvG44A2rT2dP91sEAcN0fmlovNAQQbuxXi2NEyn091TnL43BnR1U-zwR6-x0w9phzbfretIkDrJog4NSfLkttXWzHMBN8Z6jVc191GM6JjvCek1bIzrmkqcFRljg3EFkAMgofTA6wabotuKYwWxkr7JQ5aq-JdB7OjjFOAlozrs3NUN8YcqAuygW4U-6TCCVI1qYO00NX-DZW5ZZwNfCl4qcyM36ydjXM4oFNzQoqumqOjieJLu_VgN3jn3NAQejl_O4FdKu9CDSEyBxGdr-TVitPxcJXbVWOhYFhAcQ6t-fA7dA7EB1ZMPbvun6fqUalP485aUXM-Kyw9q3XjqrXX4uIs51v3diDFwGXhuHtcD847nafj9R8jBnNKL5wP1e6D85bFntmGcFn32PNhVGIdEedV-AZriKUT_-ygndmwU-eVGMvhe4TcPTvX1BWh8UfNK8TacnZ2ggeLJ-svQ6lSl2eq4mvJ9Qx1xTg35J6y3wJWR1ACgs0ghzTBDHH3vWGVr-S1_sJlBoDm3Z1fprS3G3zzDu_rCn24I8_g3ps7fKwVcrHS3-D6px5KBvHnHf4U9et3FzHBIycmQpznHxsP7FSbsk6Nfat2uaiDk7hCjt-aDE9wP6deaESqhEVw4_f9qhqsIYnrYtpzoGEoiDoUan8zn4eVt3dWOHfP5oVZ7OG9h-Xou0JCDEvX3oL2jk43GmosjzcUadN21AcjfGosdj2nG6QxTaw96q7MbiNJr1lveDHPbZhHkOx6IO49WuosbRIV2Q1bfmJ7e-KCmqQeVmevkmo8rv5WvRIxAW1Im2YJf14oQRA64uR9AoIXfP4O7o6Y64bx53m1ISPFn2TdTnPSO5t1VGChiKtWgwx2aCKqyWTVKzUr0Jiyao_Mf1xMfLDx9NkycbvUN1W_G7rCNuTx4UrIc7NmX9ylnTAe1OWKM9lllpq99-TLToIULhcexvRzl2hEXBatRV_nqzHhviPTX-KkFoYUF5hqhax9TXRYbBON7UEWz2Np9csDzZfM2Y7Mrg0zfc1U0WVq594INiFoPeUSU9f7oNumvH_dMW82VqT-_AHvD054ycdXg93vm-xan7t1oju67eco9-tRLiZ_4Pj2GrIrI9s7J7W74Xj2e-ey_52x7J8wla3-dYn0XynllwdN9QWqRGSZOJgFpqCkHyWTNLZ3iGQPm72_BSe_Ighm_l3Xx4ROqTwwRaG1XBcp5ZrJzoUtpqAoNMvZJ42hKDU8pCxKYY7Vu6ovnJGM5lAxHtH2AlgPaXUZDGt7l6s77J37dv5ryPAyywotO1ejUFBIvMtxJWnNBxRJ4iD-oyPv_C8_7L6sIN51vh-bid82FD-biZ9r785peG-EDS9Nr0dHzvCHps2Xxs13T5sHl_psOH3TtFDdZQPxD6yp0tWd0MkEbkwAUTVATTpRNXMWd9NgOJns3aTZLTtnqB5B5Hu-5--YvZ04mDsznZbEi0QO0GuW7ev_TQopTFnwzK5gOcVLP4gxCgOyCKMlWZCpT8giQHRFV_4KhdNlSJeNK_-O5Y5q05Icl_PtfDYp-TsXBz7JGC-Pkx0vK7jU1HeYi5hmBroQih3d0i9caXvL4JlJswSCjaQxjjSNO1cRB0r41YcT693P1ZQc-XD02iSciJEFUeoWsQfQ6xWQi5ci3OrFixoXGEd_Eca_0V1OuTl8Cw4TXGbaQUsK4zIvaNzY-LuU_3RJhqevZRiA3K2_P4j2HRq6nBFMyLtYX2v4xBQ1fg037hb4Hx3-04UJ_--M_dt7ip-x_zP2f8b-PbH_RBOzdST-nwVVkAvda6T_zDQQIEKDmR8m4SKZ0lns08iP8WoWzILZdBrMQj9cBnT5Mw3876eBuxn__4j9QUQ_xI9BvApW-IE-ThdohpZTfzp7SB_RNKRR4PvEn9PZyk-wvyDRAoVxFEQJCtEDe0Q-mvlLNEUonIczLw79cL7E02A5wzO8nIOZT3PMMs9EoSfk7oEpVdLHqR-Gq_Ahw4Rmyv72DKFKGwiEzw_y0YYtKXcKzPyMKa1aFJrpzP5gze0In83H-vynQPgMfyv5RLO8_vWW_YlYdZx0Cc_-Lqu6flTvbH9JVnvT3H8oZfZ4X44B6NXKqAB6rcTcP6J_BwAA__8STeWF">