1 // RUN: %clang_cc1 -triple x86_64-apple-darwin9 %s -std=c++14 -fcoroutines-ts -fsyntax-only -Wignored-qualifiers -Wno-error=return-type -verify -fblocks -Wall -Wextra -Wno-error=unreachable-code
2 #include "Inputs/std-coroutine-exp-namespace.h"
3 
4 using std::experimental::suspend_always;
5 using std::experimental::suspend_never;
6 
7 struct awaitable {
8   bool await_ready();
9   void await_suspend(std::experimental::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::experimental::coroutine_traits<void> { using promise_type = promise_void; };
76 
77 template <typename T1>
78 struct std::experimental::coroutine_traits<void, T1> { using promise_type = promise_void_return_value; };
79 
80 template <typename... T>
81 struct std::experimental::coroutine_traits<float, T...> { using promise_type = promise_float; };
82 
83 template <typename... T>
84 struct std::experimental::coroutine_traits<int, T...> { using promise_type = promise_int; };
85 
test0()86 void test0() { co_await a; } // expected-warning {{support for std::experimental::coroutine_traits will be removed}}
87 // expected-note@Inputs/std-coroutine-exp-namespace.h:8 {{'coroutine_traits' declared here}}
test1()88 float test1() { co_await a; }
89 
test2()90 int test2() {
91   co_await a;
92 } // expected-warning {{non-void coroutine does not return a value}}
93 
test2a(bool b)94 int test2a(bool b) {
95   if (b)
96     co_return 42;
97 } // expected-warning {{non-void coroutine does not return a value in all control paths}}
98 
test3()99 int test3() {
100   co_await a;
101 b:
102   goto b;
103 }
104 
test4()105 int test4() {
106   co_return 42;
107 }
108 
test5(int)109 void test5(int) {
110   co_await a;
111 } // expected-warning {{non-void coroutine does not return a value}}
112 
test6(int x)113 void test6(int x) {
114   if (x)
115     co_return 42;
116 } // expected-warning {{non-void coroutine does not return a value in all control paths}}
117 
test7(int y)118 void test7(int y) {
119   if (y)
120     co_return 42;
121   else
122     co_return 101;
123 }
124 
test8()125 VoidTagReturnVoid test8() {
126   co_await a;
127 }
128 
test9(bool b)129 VoidTagReturnVoid test9(bool b) {
130   if (b)
131     co_return;
132 }
133 
test10()134 VoidTagReturnValue test10() {
135   co_await a;
136 } // expected-warning {{non-void coroutine does not return a value}}
137 
test11(bool b)138 VoidTagReturnValue test11(bool b) {
139   if (b)
140     co_return 42;
141 } // expected-warning {{non-void coroutine does not return a value in all control paths}}
142