<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/77111>77111</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
Crash on invalid coroutine code
</td>
</tr>
<tr>
<th>Labels</th>
<td>
clang
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
ilya-biryukov
</td>
</tr>
</table>
<pre>
See [godbolt](https://gcc.godbolt.org/z/To4dcc16j).
```cpp
#include <coroutine>
struct Status {
~Status();
};
struct awaiter {
struct promise_type {};
bool await_ready();
// Note: std::coroutine_handle<> was intended.
Status await_suspend(std::coroutine_handle<> coro) { coro.destroy(); }
};
awaiter five();
awaiter sum() {
co_return co_await five();
}
```
Expected: Clang shows an error that `Status` must be `bool`, `void` or `coroutine_handle`.
Actual: Clang crashes and produces the following output (assertions enabled):
```shell
foo.cc:28:10: error: no member named 'initial_suspend' in 'std::coroutine_traits<SOr<int>>::promise_type'
28 | SOr<int> sum() { co_return co_await five(); }
| ^~~
clang++: .../llvm-project/llvm/include/llvm/Support/Casting.h:706: auto llvm::cast_if_present(Y *) [X = clang::CallExpr, Y = clang::Expr]: Assertion `isa<X>(Val) && "cast_if_present<Ty>() argument of incompatible type!"' failed.
...
#0 0x0000558a59ddfba4 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) .../llvm-project/llvm/lib/Support/Unix/Signals.inc:723:13
...
#10 0x0000558a5c552876 buildCoroutineHandle .../llvm-project/clang/lib/Sema/SemaCoroutine.cpp:0:0
#11 0x0000558a5c552876 buildCoawaitCalls(clang::Sema&, clang::VarDecl*, clang::SourceLocation, clang::Expr*) .../llvm-project/clang/lib/Sema/SemaCoroutine.cpp:497:7
#12 0x0000558a5c551791 clang::Sema::BuildResolvedCoawaitExpr(clang::SourceLocation, clang::Expr*, clang::Expr*, bool) .../llvm-project/clang/lib/Sema/SemaCoroutine.cpp:0:7
```
Clang does not check the return type is `std::coroutine_handle` and because `Status` has a destructor, a call to it will have wrappers for running cleanups. Whereas the coroutine code expects `CallExpr` and the corresponding cast fails.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJykVk9z3LYO_zTcCyYaiVr92cMeZNmed3jzXqdO0-TkoUjsigmX1JCU19tDPnuHlPZv7aSdemSbAiAAP-AnQMw5udWIa1LckeJ-wUbfG7uW6sA-dNIexm_mZdEZcVg_IQIp7rZGdEZ5UtwTWvfeD47kDaGPhD5uOU9mdWLsltDHPwh9_GiWgvOs_EroKiHpPUkbUqbTxYdhltBcaq5GgUDylhtrRi81kvxh1se_ztuRe3jyzI8OSHU3iQEAvk9CQmtCVySfNaS6P58vXbA9kx7ttY9ZN1izkw6f_WHAaHDhJJh1xqjJwbNFJg63MSfDqSTwP-OR5A04L0Kd8uaE7blnWigkeUvyB9gzB1J71AJFco41Q52iudENqAWh9c-8BTGhq5B9PCcCnbfmnCoEUO-U6FibjXzBG2xHlRt3k-a6gNw8W_Sj1eEUbd9ycg59pMFl9IfXAbnHgA9axfQWXG_2DpgGtNZY8D3zQMp0bniZwm50HjoMwtCb4JC24e7FSBEMjA13f6lVmc6VbrgfmTpH5Ja5HkNMEdggRo4OfI-wMUqZvdRbMKMfRg-E1sw5tF4a7QA16xSKCLa5weh6VGqSbYxJOCd5Q2uSN1kaAkds4aAN7HDXoQXNdiiA0Epq6SVT5_5XIHVQvEEDb5n0juTt0_8tyVupfXiHwhXsLqlNaHXqHK2BVC1cPnPd45-29kwoiD_BHSkevn-fhDzUldC7cOUNJElC6KNSL7sPgzVfkfv5ltDHeQ6cBU_jMBgbLFrmvNTbpCd5U6Vl8MRGbyAaToVgzj_LzfNg0aH2hNZfgNAmoijuPgPJ72HKJZq3TKmH18EGvny5VUZFcR-iNMceBx5Jx0jefg5FpfUnpqJzWhJaAqH0NoO8_XiYTIMds9txh9qD2YDU3OwG5mWnEKaOZITS0N4Nk-o0B0KxjjMlTyF9TdM0LYqaFSshNh1bXuB3BzcdfrFS-yfP-LePlvHQp7ORZftn47xFtot5t2HyhOx-1BYlu6te_KblaxDIrWbKJVIHQlc0D4zObxInNM-uEudFQeuqhG6USrRH8v4nvpZvZzET6JgG7tj87_R0EpZJ3qTx9xQ2-0HYSONAgbA2Lho_eY-FuZB-YvYeuYpsulI8mdFy_K_hLDDkRjmxq3m3un8b13JVhQKfkdEbZFm1yuAWRTzdBbi_ojPqBY-wp7zqfwzjPWkcvP8aZHoB8a3lMI1nYdCBNh54j_xbHMzzbIorW7rwlr6_Iss0DvYOORsdXq-SnjlgELflyL2Jg4EBZ0qBNyA97KVS0LMXhL1lw4DWwcZYsKPWYS1whUyPg0vg9x4tsmltnFIAbgQCxhUXszwNoDmp2dqiG4wW0SNzPs4DN79MC7HOxSpfsQWusypdLstVsaKLfl2l1VLU3YaXneBik63KuqZ8uUqLXGzqZbeQa5rSZZqlRVYsyzxLGE1XFa_psu5YhxtOlinumFRJ6F_4hFtI50ZcV1WWZQvFOlQufihSOreUhm9Gu4797satI8tUSefd2YOXXuG6DRsVjAapX5iS4qYki9Gq9c3HpPT92CXc7C5m0DWtYnKO0MeY358BAAD__2QjSRQ">