xref: /llvm-project/clang/test/CodeGenCXX/ubsan-coroutines.cpp (revision ec117158a390a0ebf64377caa5abd0c976df8f7a)
1 // This test merely verifies that emitting the object file does not cause a
2 // crash when the LLVM coroutines passes are run.
3 // RUN: %clang_cc1 -emit-obj -std=c++2a -fsanitize=null %s -o %t.o
4 
5 namespace std {
6 template <typename R, typename... T> struct coroutine_traits {
7   using promise_type = typename R::promise_type;
8 };
9 
10 template <class Promise = void> struct coroutine_handle;
11 template <> struct coroutine_handle<void> {
12   static coroutine_handle from_address(void *) noexcept;
13   coroutine_handle() = default;
14   template <class PromiseType>
15   coroutine_handle(coroutine_handle<PromiseType>) noexcept;
16 };
17 template <class Promise> struct coroutine_handle : coroutine_handle<void> {
18   coroutine_handle() = default;
19   static coroutine_handle from_address(void *) noexcept;
20 };
21 } // namespace std
22 
23 struct suspend_always {
24   bool await_ready() noexcept;
25   void await_suspend(std::coroutine_handle<>) noexcept;
26   void await_resume() noexcept;
27 };
28 
29 struct task {
30   struct promise_type {
get_return_objecttask::promise_type31     task get_return_object() { return task(); }
initial_suspendtask::promise_type32     suspend_always initial_suspend() { return {}; }
final_suspendtask::promise_type33     suspend_always final_suspend() noexcept { return {}; }
return_voidtask::promise_type34     void return_void() {}
unhandled_exceptiontask::promise_type35     void unhandled_exception() {}
36   };
37 };
38 
39 struct awaitable {
awaitawaitable40   task await() { (void)co_await *this; }
await_readyawaitable41   bool await_ready() { return false; }
await_suspendawaitable42   bool await_suspend(std::coroutine_handle<> awaiter) { return false; }
await_resumeawaitable43   bool await_resume() { return false; }
44 };
45 
main()46 int main() {
47   awaitable a;
48   a.await();
49 }
50