1 // RUN: %clang_cc1 -triple x86_64-apple-darwin9 %s -std=c++20 -fsyntax-only -Wignored-qualifiers -Wno-error=return-type -verify -fblocks -Wall -Wextra -Wno-error=unreachable-code 2 #include "Inputs/std-coroutine.h" 3 4 using std::suspend_always; 5 using std::suspend_never; 6 7 struct awaitable { 8 bool await_ready(); 9 void await_suspend(std::coroutine_handle<>); // FIXME: coroutine_handle 10 void await_resume(); 11 } a; 12 13 struct promise_void { 14 void get_return_object(); 15 suspend_always initial_suspend(); 16 suspend_always final_suspend() noexcept; 17 void return_void(); 18 void unhandled_exception(); 19 }; 20 21 struct promise_void_return_value { 22 void get_return_object(); 23 suspend_always initial_suspend(); 24 suspend_always final_suspend() noexcept; 25 void unhandled_exception(); 26 void return_value(int); 27 }; 28 29 struct VoidTagNoReturn { 30 struct promise_type { 31 VoidTagNoReturn get_return_object(); 32 suspend_always initial_suspend(); 33 suspend_always final_suspend() noexcept; 34 void unhandled_exception(); 35 }; 36 }; 37 38 struct VoidTagReturnValue { 39 struct promise_type { 40 VoidTagReturnValue get_return_object(); 41 suspend_always initial_suspend(); 42 suspend_always final_suspend() noexcept; 43 void unhandled_exception(); 44 void return_value(int); 45 }; 46 }; 47 48 struct VoidTagReturnVoid { 49 struct promise_type { 50 VoidTagReturnVoid get_return_object(); 51 suspend_always initial_suspend(); 52 suspend_always final_suspend() noexcept; 53 void unhandled_exception(); 54 void return_void(); 55 }; 56 }; 57 58 struct promise_float { 59 float get_return_object(); 60 suspend_always initial_suspend(); 61 suspend_always final_suspend() noexcept; 62 void return_void(); 63 void unhandled_exception(); 64 }; 65 66 struct promise_int { 67 int get_return_object(); 68 suspend_always initial_suspend(); 69 suspend_always final_suspend() noexcept; 70 void return_value(int); 71 void unhandled_exception(); 72 }; 73 74 template <> 75 struct std::coroutine_traits<void> { using promise_type = promise_void; }; 76 77 template <typename T1> 78 struct std::coroutine_traits<void, T1> { using promise_type = promise_void_return_value; }; 79 80 template <typename... T> 81 struct std::coroutine_traits<float, T...> { using promise_type = promise_float; }; 82 83 template <typename... T> 84 struct std::coroutine_traits<int, T...> { using promise_type = promise_int; }; 85 test0()86void test0() { co_await a; } test1()87float test1() { co_await a; } 88 test2()89int test2() { 90 co_await a; 91 } // expected-warning {{non-void coroutine does not return a value}} 92 test2a(bool b)93int test2a(bool b) { 94 if (b) 95 co_return 42; 96 } // expected-warning {{non-void coroutine does not return a value in all control paths}} 97 test3()98int test3() { 99 co_await a; 100 b: 101 goto b; 102 } 103 test4()104int test4() { 105 co_return 42; 106 } 107 test5(int)108void test5(int) { 109 co_await a; 110 } // expected-warning {{non-void coroutine does not return a value}} 111 test6(int x)112void test6(int x) { 113 if (x) 114 co_return 42; 115 } // expected-warning {{non-void coroutine does not return a value in all control paths}} 116 test7(int y)117void test7(int y) { 118 if (y) 119 co_return 42; 120 else 121 co_return 101; 122 } 123 test8()124VoidTagReturnVoid test8() { 125 co_await a; 126 } 127 test9(bool b)128VoidTagReturnVoid test9(bool b) { 129 if (b) 130 co_return; 131 } 132 test10()133VoidTagReturnValue test10() { 134 co_await a; 135 } // expected-warning {{non-void coroutine does not return a value}} 136 test11(bool b)137VoidTagReturnValue test11(bool b) { 138 if (b) 139 co_return 42; 140 } // expected-warning {{non-void coroutine does not return a value in all control paths}} 141