]>
Commit | Line | Data |
---|---|---|
223e47cc LB |
1 | // RUN: %clang %s -fsyntax-only -Wignored-qualifiers -Wno-error=return-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. | |
6 | int t14() { | |
7 | return; // expected-warning {{non-void function 't14' should return a value}} | |
8 | } | |
9 | ||
10 | void t15() { | |
11 | return 1; // expected-warning {{void function 't15' should not return a value}} | |
12 | } | |
13 | ||
14 | int unknown(); | |
15 | ||
16 | void test0() { | |
17 | } | |
18 | ||
19 | int test1() { | |
20 | } // expected-warning {{control reaches end of non-void function}} | |
21 | ||
22 | int test2() { | |
23 | a: goto a; | |
24 | } | |
25 | ||
26 | int test3() { | |
27 | goto a; | |
28 | a: ; | |
29 | } // expected-warning {{control reaches end of non-void function}} | |
30 | ||
31 | ||
32 | void halt() { | |
33 | a: goto a; | |
34 | } | |
35 | ||
36 | void halt2() __attribute__((noreturn)); | |
37 | ||
38 | int test4() { | |
39 | halt2(); | |
40 | } | |
41 | ||
42 | int test5() { | |
43 | halt2(), (void)1; | |
44 | } | |
45 | ||
46 | int test6() { | |
47 | 1, halt2(); | |
48 | } | |
49 | ||
50 | int j; | |
51 | int unknown_nohalt() { | |
52 | return j; | |
53 | } | |
54 | ||
55 | int test7() { | |
56 | unknown(); | |
57 | } // expected-warning {{control reaches end of non-void function}} | |
58 | ||
59 | int test8() { | |
60 | (void)(1 + unknown()); | |
61 | } // expected-warning {{control reaches end of non-void function}} | |
62 | ||
63 | int halt3() __attribute__((noreturn)); | |
64 | ||
65 | int test9() { | |
66 | (void)(halt3() + unknown()); | |
67 | } | |
68 | ||
69 | int test10() { | |
70 | (void)(unknown() || halt3()); | |
71 | } // expected-warning {{control may reach end of non-void function}} | |
72 | ||
73 | int test11() { | |
74 | (void)(unknown() && halt3()); | |
75 | } // expected-warning {{control may reach end of non-void function}} | |
76 | ||
77 | int test12() { | |
78 | (void)(halt3() || unknown()); | |
79 | } | |
80 | ||
81 | int test13() { | |
82 | (void)(halt3() && unknown()); | |
83 | } | |
84 | ||
85 | int test14() { | |
86 | (void)(1 || unknown()); | |
87 | } // expected-warning {{control reaches end of non-void function}} | |
88 | ||
89 | int test15() { | |
90 | (void)(0 || unknown()); | |
91 | } // expected-warning {{control reaches end of non-void function}} | |
92 | ||
93 | int test16() { | |
94 | (void)(0 && unknown()); | |
95 | } // expected-warning {{control reaches end of non-void function}} | |
96 | ||
97 | int test17() { | |
98 | (void)(1 && unknown()); | |
99 | } // expected-warning {{control reaches end of non-void function}} | |
100 | ||
101 | int test18() { | |
102 | (void)(unknown_nohalt() && halt3()); | |
103 | } // expected-warning {{control may reach end of non-void function}} | |
104 | ||
105 | int test19() { | |
106 | (void)(unknown_nohalt() && unknown()); | |
107 | } // expected-warning {{control reaches end of non-void function}} | |
108 | ||
109 | int 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 | ||
117 | int test21() { | |
118 | int i; | |
119 | if (i) | |
120 | return 0; | |
121 | else if (1) | |
122 | return 2; | |
123 | } | |
124 | ||
125 | int test22() { | |
126 | int i; | |
127 | switch (i) default: ; | |
128 | } // expected-warning {{control reaches end of non-void function}} | |
129 | ||
130 | int 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 | ||
140 | int 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 | ||
152 | int test25() { | |
153 | 1 ? halt3() : unknown(); | |
154 | } | |
155 | ||
156 | int test26() { | |
157 | 0 ? halt3() : unknown(); | |
158 | } // expected-warning {{control reaches end of non-void function}} | |
159 | ||
160 | int j; | |
161 | void (*fptr)() __attribute__((noreturn)); | |
162 | int 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 | |
192 | void test28() __attribute__((noreturn)); | |
193 | void test28(x) { while (1) { } } | |
194 | ||
195 | void exit(int); | |
196 | int test29() { | |
197 | exit(1); | |
198 | } | |
199 | ||
200 | #include <setjmp.h> | |
201 | jmp_buf test30_j; | |
202 | int 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 | ||
213 | typedef void test31_t(int status); | |
214 | void test31(test31_t *callback __attribute__((noreturn))); | |
215 | ||
216 | void test32() { | |
217 | ^ (void) { while (1) { } }(); | |
218 | ^ (void) { if (j) while (1) { } }(); | |
219 | while (1) { } | |
220 | } | |
221 | ||
222 | void 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. | |
228 | static inline int si_has_missing_return() {} // expected-warning{{control reaches end of non-void function}} | |
229 | static inline int si_has_missing_return_2() {}; // expected-warning{{control reaches end of non-void function}} | |
230 | static inline int si_forward(); | |
231 | static 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 | ||
236 | int test_static_inline(int x) { | |
237 | si_forward(); | |
238 | return x ? si_has_missing_return_2() : si_has_missing_return_3(x); | |
239 | } | |
240 | static inline int si_forward() {} // expected-warning{{control reaches end of non-void function}} | |
241 | ||
242 | // Test warnings on ignored qualifiers on return types. | |
243 | const int ignored_c_quals(); // expected-warning{{'const' type qualifier on return type has no effect}} | |
244 | const volatile int ignored_cv_quals(); // expected-warning{{'const volatile' type qualifiers on return type have no effect}} | |
245 | char* 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. | |
249 | enum Cases { C1, C2, C3, C4 }; | |
250 | int 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 | ||
259 | // PR12318 - Don't give a may reach end of non-void function warning. | |
260 | int test34(int x) { | |
261 | if (x == 1) { | |
262 | return 3; | |
263 | } else if ( x == 2 || 1) { | |
264 | return 5; | |
265 | } | |
266 | } |