Clang Project

clang_source_code/test/SemaCXX/coreturn.cpp
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.h"
3
4using std::experimental::suspend_always;
5using std::experimental::suspend_never;
6
7struct awaitable {
8  bool await_ready();
9  void await_suspend(std::experimental::coroutine_handle<>); // FIXME: coroutine_handle
10  void await_resume();
11} a;
12
13struct promise_void {
14  void get_return_object();
15  suspend_always initial_suspend();
16  suspend_always final_suspend();
17  void return_void();
18  void unhandled_exception();
19};
20
21struct promise_void_return_value {
22  void get_return_object();
23  suspend_always initial_suspend();
24  suspend_always final_suspend();
25  void unhandled_exception();
26  void return_value(int);
27};
28
29struct VoidTagNoReturn {
30  struct promise_type {
31    VoidTagNoReturn get_return_object();
32    suspend_always initial_suspend();
33    suspend_always final_suspend();
34    void unhandled_exception();
35  };
36};
37
38struct VoidTagReturnValue {
39  struct promise_type {
40    VoidTagReturnValue get_return_object();
41    suspend_always initial_suspend();
42    suspend_always final_suspend();
43    void unhandled_exception();
44    void return_value(int);
45  };
46};
47
48struct VoidTagReturnVoid {
49  struct promise_type {
50    VoidTagReturnVoid get_return_object();
51    suspend_always initial_suspend();
52    suspend_always final_suspend();
53    void unhandled_exception();
54    void return_void();
55  };
56};
57
58struct promise_float {
59  float get_return_object();
60  suspend_always initial_suspend();
61  suspend_always final_suspend();
62  void return_void();
63  void unhandled_exception();
64};
65
66struct promise_int {
67  int get_return_object();
68  suspend_always initial_suspend();
69  suspend_always final_suspend();
70  void return_value(int);
71  void unhandled_exception();
72};
73
74template <>
75struct std::experimental::coroutine_traits<void> { using promise_type = promise_void; };
76
77template <typename T1>
78struct std::experimental::coroutine_traits<void, T1> { using promise_type = promise_void_return_value; };
79
80template <typename... T>
81struct std::experimental::coroutine_traits<float, T...> { using promise_type = promise_float; };
82
83template <typename... T>
84struct std::experimental::coroutine_traits<int, T...> { using promise_type = promise_int; };
85
86void test0() { co_await a; }
87float test1() { co_await a; }
88
89int test2() {
90  co_await a;
91} // expected-warning {{control reaches end of coroutine; which is undefined behavior because the promise type 'std::experimental::coroutine_traits<int>::promise_type' (aka 'promise_int') does not declare 'return_void()'}}
92
93int test2a(bool b) {
94  if (b)
95    co_return 42;
96} // expected-warning {{control may reach end of coroutine; which is undefined behavior because the promise type 'std::experimental::coroutine_traits<int, bool>::promise_type' (aka 'promise_int') does not declare 'return_void()'}}
97
98int test3() {
99  co_await a;
100b:
101  goto b;
102}
103
104int test4() {
105  co_return 42;
106}
107
108void test5(int) {
109  co_await a;
110} // expected-warning {{control reaches end of coroutine; which is undefined behavior because}}
111
112void test6(int x) {
113  if (x)
114    co_return 42;
115} // expected-warning {{control may reach end of coroutine; which is undefined behavior because}}
116
117void test7(int y) {
118  if (y)
119    co_return 42;
120  else
121    co_return 101;
122}
123
124VoidTagReturnVoid test8() {
125  co_await a;
126}
127
128VoidTagReturnVoid test9(bool b) {
129  if (b)
130    co_return;
131}
132
133VoidTagReturnValue test10() {
134  co_await a;
135} // expected-warning {{control reaches end of coroutine}}
136
137VoidTagReturnValue test11(bool b) {
138  if (b)
139    co_return 42;
140} // expected-warning {{control may reach end of coroutine}}
141