Issue |
77111
|
Summary |
Crash on invalid coroutine code
|
Labels |
clang
|
Assignees |
|
Reporter |
ilya-biryukov
|
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.
_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs