xref: /llvm-project/clang/test/SemaCXX/coreturn.cpp (revision ec117158a390a0ebf64377caa5abd0c976df8f7a)
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()86 void test0() { co_await a; }
test1()87 float test1() { co_await a; }
88 
test2()89 int test2() {
90   co_await a;
91 } // expected-warning {{non-void coroutine does not return a value}}
92 
test2a(bool b)93 int 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()98 int test3() {
99   co_await a;
100 b:
101   goto b;
102 }
103 
test4()104 int test4() {
105   co_return 42;
106 }
107 
test5(int)108 void test5(int) {
109   co_await a;
110 } // expected-warning {{non-void coroutine does not return a value}}
111 
test6(int x)112 void 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)117 void test7(int y) {
118   if (y)
119     co_return 42;
120   else
121     co_return 101;
122 }
123 
test8()124 VoidTagReturnVoid test8() {
125   co_await a;
126 }
127 
test9(bool b)128 VoidTagReturnVoid test9(bool b) {
129   if (b)
130     co_return;
131 }
132 
test10()133 VoidTagReturnValue test10() {
134   co_await a;
135 } // expected-warning {{non-void coroutine does not return a value}}
136 
test11(bool b)137 VoidTagReturnValue 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