1// RUN: %clang %s -fsyntax-only -Wignored-qualifiers -Wreturn-type -Xclang -verify -fblocks -Wno-unreachable-code -Wno-unused-value
2
3// clang emits the following warning by default.
4// With GCC, -pedantic, -Wreturn-type or -Wall are required to produce the
5// following warning.
6int t14() {
7  return; // expected-warning {{non-void function 't14' should return a value}}
8}
9
10void t15() {
11  return 1; // expected-warning {{void function 't15' should not return a value}}
12}
13
14int unknown();
15
16void test0() {
17}
18
19int test1() {
20} // expected-warning {{control reaches end of non-void function}}
21
22int test2() {
23  a: goto a;
24}
25
26int test3() {
27  goto a;
28  a: ;
29} // expected-warning {{control reaches end of non-void function}}
30
31
32void halt() {
33  a: goto a;
34}
35
36void halt2() __attribute__((noreturn));
37
38int test4() {
39  halt2();
40}
41
42int test5() {
43  halt2(), (void)1;
44}
45
46int test6() {
47  1, halt2();
48}
49
50int j;
51int unknown_nohalt() {
52  return j;
53}
54
55int test7() {
56  unknown();
57} // expected-warning {{control reaches end of non-void function}}
58
59int test8() {
60  (void)(1 + unknown());
61} // expected-warning {{control reaches end of non-void function}}
62
63int halt3() __attribute__((noreturn));
64
65int test9() {
66  (void)(halt3() + unknown());
67}
68
69int test10() {
70  (void)(unknown() || halt3());
71} // expected-warning {{control may reach end of non-void function}}
72
73int test11() {
74  (void)(unknown() && halt3());
75} // expected-warning {{control may reach end of non-void function}}
76
77int test12() {
78  (void)(halt3() || unknown());
79}
80
81int test13() {
82  (void)(halt3() && unknown());
83}
84
85int test14() {
86  (void)(1 || unknown());
87} // expected-warning {{control reaches end of non-void function}}
88
89int test15() {
90  (void)(0 || unknown());
91} // expected-warning {{control reaches end of non-void function}}
92
93int test16() {
94  (void)(0 && unknown());
95} // expected-warning {{control reaches end of non-void function}}
96
97int test17() {
98  (void)(1 && unknown());
99} // expected-warning {{control reaches end of non-void function}}
100
101int test18() {
102  (void)(unknown_nohalt() && halt3());
103} // expected-warning {{control may reach end of non-void function}}
104
105int test19() {
106  (void)(unknown_nohalt() && unknown());
107} // expected-warning {{control reaches end of non-void function}}
108
109int test20() {
110  int i;
111  if (i)
112    return 0;
113  else if (0)
114    return 2;
115} // expected-warning {{control may reach end of non-void function}}
116
117int test21() {
118  int i;
119  if (i)
120    return 0;
121  else if (1)
122    return 2;
123}
124
125int test22() {
126  int i;
127  switch (i) default: ;
128} // expected-warning {{control reaches end of non-void function}}
129
130int test23() {
131  int i;
132  switch (i) {
133  case 0:
134    return 0;
135  case 2:
136    return 2;
137  }
138} // expected-warning {{control may reach end of non-void function}}
139
140int test24() {
141  int i;
142  switch (i) {
143    case 0:
144    return 0;
145  case 2:
146    return 2;
147  default:
148    return -1;
149  }
150}
151
152int test25() {
153  1 ? halt3() : unknown();
154}
155
156int test26() {
157  0 ? halt3() : unknown();
158} // expected-warning {{control reaches end of non-void function}}
159
160int j;
161void (*fptr)() __attribute__((noreturn));
162int test27() {
163  switch (j) {
164  case 1:
165    do { } while (1);
166    break;
167  case 2:
168    for (;;) ;
169    break;
170  case 3:
171    for (;1;) ;
172    for (;0;) {
173      goto done;
174    }
175    return 1;
176  case 4:
177    while (0) { goto done; }
178    return 1;
179  case 5:
180    while (1) { return 1; }
181    break;
182  case 6:
183    fptr();
184    break;
185  default:
186    return 1;
187  }
188  done: ;
189}
190
191// PR4624
192void test28() __attribute__((noreturn));
193void test28(x) { while (1) { } }
194
195void exit(int);
196int test29() {
197  exit(1);
198}
199
200#include <setjmp.h>
201jmp_buf test30_j;
202int test30() {
203  if (j)
204    longjmp(test30_j, 1);
205  else
206#if defined(_WIN32) || defined(_WIN64) || defined(__CYGWIN__)
207    longjmp(test30_j, 2);
208#else
209    _longjmp(test30_j, 1);
210#endif
211}
212
213typedef void test31_t(int status);
214void test31(test31_t *callback __attribute__((noreturn)));
215
216void test32() {
217  ^ (void) { while (1) { } }();
218  ^ (void) { if (j) while (1) { } }();
219  while (1) { }
220}
221
222void test33() {
223  if (j) while (1) { }
224}
225
226// Test that 'static inline' functions are only analyzed for CFG-based warnings
227// when they are used.
228static inline int si_has_missing_return() {} // expected-warning{{control reaches end of non-void function}}
229static inline int si_has_missing_return_2() {}; // expected-warning{{control reaches end of non-void function}}
230static inline int si_forward();
231static inline int si_has_missing_return_3(int x) {
232  if (x)
233   return si_has_missing_return_3(x+1);
234} // expected-warning{{control may reach end of non-void function}}
235
236int test_static_inline(int x) {
237  si_forward();
238  return x ? si_has_missing_return_2() : si_has_missing_return_3(x);
239}
240static inline int si_forward() {} // expected-warning{{control reaches end of non-void function}}
241
242// Test warnings on ignored qualifiers on return types.
243const int ignored_c_quals(); // expected-warning{{'const' type qualifier on return type has no effect}}
244const volatile int ignored_cv_quals(); // expected-warning{{'const volatile' type qualifiers on return type have no effect}}
245char* const volatile restrict ignored_cvr_quals(); // expected-warning{{'const volatile restrict' type qualifiers on return type have no effect}}
246
247// Test that for switch(enum) that if the switch statement covers all the cases
248// that we don't consider that for -Wreturn-type.
249enum Cases { C1, C2, C3, C4 };
250int test_enum_cases(enum Cases C) {
251  switch (C) {
252  case C1: return 1;
253  case C2: return 2;
254  case C4: return 3;
255  case C3: return 4;
256  }
257} // no-warning
258