1 | // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 -Wimplicit-fallthrough %s |
2 | |
3 | |
4 | int fallthrough(int n) { |
5 | switch (n / 10) { |
6 | if (n - 1) { |
7 | n = 100; |
8 | } else if (n - 2) { |
9 | n = 101; |
10 | } else if (n - 3) { |
11 | n = 102; |
12 | } |
13 | case -1: // no warning here, ignore fall-through from unreachable code |
14 | ; |
15 | case 0: {// expected-warning{{unannotated fall-through between switch labels}} expected-note{{insert '[[clang::fallthrough]];' to silence this warning}} expected-note{{insert 'break;' to avoid fall-through}} |
16 | } |
17 | case 1: // expected-warning{{unannotated fall-through between switch labels}} expected-note{{insert '[[clang::fallthrough]];' to silence this warning}} expected-note{{insert 'break;' to avoid fall-through}} |
18 | n += 100 ; |
19 | case 3: // expected-warning{{unannotated fall-through between switch labels}} expected-note{{insert '[[clang::fallthrough]];' to silence this warning}} expected-note{{insert 'break;' to avoid fall-through}} |
20 | if (n > 0) |
21 | n += 200; |
22 | case 4: // expected-warning{{unannotated fall-through between switch labels}} expected-note{{insert '[[clang::fallthrough]];' to silence this warning}} expected-note{{insert 'break;' to avoid fall-through}} |
23 | if (n < 0) |
24 | ; |
25 | case 5: // expected-warning{{unannotated fall-through between switch labels}} expected-note{{insert '[[clang::fallthrough]];' to silence this warning}} expected-note{{insert 'break;' to avoid fall-through}} |
26 | switch (n) { |
27 | case 111: |
28 | break; |
29 | case 112: |
30 | break; |
31 | case 113: |
32 | break ; |
33 | } |
34 | case 6: // expected-warning{{unannotated fall-through between switch labels}} expected-note{{insert '[[clang::fallthrough]];' to silence this warning}} expected-note{{insert 'break;' to avoid fall-through}} |
35 | n += 300; |
36 | case 66: // expected-warning{{unannotated fall-through between switch labels}} expected-note{{insert 'break;' to avoid fall-through}} |
37 | case 67: |
38 | case 68: |
39 | break; |
40 | } |
41 | switch (n / 15) { |
42 | label_default: |
43 | default: |
44 | n += 333; |
45 | if (n % 10) |
46 | goto label_default; |
47 | break; |
48 | case 70: |
49 | n += 335; |
50 | break; |
51 | } |
52 | switch (n / 20) { |
53 | case 7: |
54 | n += 400; |
55 | [[clang::fallthrough]]; |
56 | case 9: // no warning here, intended fall-through marked with an attribute |
57 | n += 800; |
58 | [[clang::fallthrough]]; |
59 | default: { // no warning here, intended fall-through marked with an attribute |
60 | if (n % 2 == 0) { |
61 | return 1; |
62 | } else { |
63 | [[clang::fallthrough]]; |
64 | } |
65 | } |
66 | case 10: // no warning here, intended fall-through marked with an attribute |
67 | if (n % 3 == 0) { |
68 | n %= 3; |
69 | } else { |
70 | [[clang::fallthrough]]; |
71 | } |
72 | case 110: // expected-warning{{unannotated fall-through between switch labels}} but no fix-it hint as we have one fall-through annotation! |
73 | n += 800; |
74 | } |
75 | switch (n / 30) { |
76 | case 11: |
77 | case 12: // no warning here, intended fall-through, no statement between labels |
78 | n += 1600; |
79 | } |
80 | switch (n / 40) { |
81 | case 13: |
82 | if (n % 2 == 0) { |
83 | return 1; |
84 | } else { |
85 | return 2; |
86 | } |
87 | case 15: // no warning here, there's no fall-through |
88 | n += 3200; |
89 | } |
90 | switch (n / 50) { |
91 | case 17: { |
92 | if (n % 2 == 0) { |
93 | return 1; |
94 | } else { |
95 | return 2; |
96 | } |
97 | } |
98 | case 19: { // no warning here, there's no fall-through |
99 | n += 6400; |
100 | return 3; |
101 | } |
102 | case 21: { // no warning here, there's no fall-through |
103 | break; |
104 | } |
105 | case 23: // no warning here, there's no fall-through |
106 | n += 128000; |
107 | break; |
108 | case 25: // no warning here, there's no fall-through |
109 | break; |
110 | } |
111 | |
112 | return n; |
113 | } |
114 | |
115 | class ClassWithDtor { |
116 | public: |
117 | ~ClassWithDtor() {} |
118 | }; |
119 | |
120 | void fallthrough2(int n) { |
121 | switch (n) { |
122 | case 0: |
123 | { |
124 | ClassWithDtor temp; |
125 | break; |
126 | } |
127 | default: // no warning here, there's no fall-through |
128 | break; |
129 | } |
130 | } |
131 | |
132 | void fallthrough3(int n) { |
133 | switch (n) { |
134 | case 1: |
135 | do { |
136 | return; |
137 | } while (0); |
138 | case 2: |
139 | do { |
140 | ClassWithDtor temp; |
141 | return; |
142 | } while (0); |
143 | case 3: |
144 | break; |
145 | } |
146 | } |
147 | |
148 | #define MY_SWITCH(X, Y, Z, U, V) switch (X) { case Y: Z; case U: V; } |
149 | #define MY_SWITCH2(X, Y, Z) switch (X) { Y; Z; } |
150 | #define MY_CASE(X, Y) case X: Y |
151 | #define MY_CASE2(X, Y, U, V) case X: Y; case U: V |
152 | |
153 | int fallthrough_macro1(int n) { |
154 | MY_SWITCH(n, 13, n *= 2, 14, break) // expected-warning{{unannotated fall-through between switch labels}} |
155 | |
156 | switch (n + 1) { |
157 | MY_CASE(33, n += 2); |
158 | MY_CASE(44, break); // expected-warning{{unannotated fall-through between switch labels}} |
159 | MY_CASE(55, n += 3); |
160 | } |
161 | |
162 | switch (n + 3) { |
163 | MY_CASE(333, return 333); |
164 | MY_CASE2(444, n += 44, 4444, break); // expected-warning{{unannotated fall-through between switch labels}} |
165 | MY_CASE(555, n += 33); |
166 | } |
167 | |
168 | MY_SWITCH2(n + 4, MY_CASE(17, n *= 3), MY_CASE(19, break)) // expected-warning{{unannotated fall-through between switch labels}} |
169 | |
170 | MY_SWITCH2(n + 5, MY_CASE(21, break), MY_CASE2(23, n *= 7, 25, break)) // expected-warning{{unannotated fall-through between switch labels}} |
171 | |
172 | return n; |
173 | } |
174 | |
175 | void fallthrough_cfgblock_with_null_successor(int x) { |
176 | (x && "") ? (void)(0) : (void)(1); |
177 | switch (x) {} |
178 | } |
179 | |
180 | int fallthrough_position(int n) { |
181 | switch (n) { |
182 | n += 300; |
183 | [[clang::fallthrough]]; // expected-warning{{fallthrough annotation in unreachable code}} |
184 | case 221: |
185 | return 1; |
186 | [[clang::fallthrough]]; // expected-warning{{fallthrough annotation in unreachable code}} |
187 | case 222: |
188 | n += 400; |
189 | case 223: // expected-warning{{unannotated fall-through between switch labels}} expected-note{{insert '[[clang::fallthrough]];' to silence this warning}} expected-note{{insert 'break;' to avoid fall-through}} |
190 | ; |
191 | } |
192 | |
193 | long p = static_cast<long>(n) * n; |
194 | switch (sizeof(p)) { |
195 | case 9: |
196 | n += static_cast<int>(p >> 32); |
197 | [[clang::fallthrough]]; // no warning here |
198 | case 5: |
199 | n += static_cast<int>(p); |
200 | [[clang::fallthrough]]; // no warning here |
201 | default: |
202 | n += 1; |
203 | break; |
204 | } |
205 | |
206 | return n; |
207 | } |
208 | |
209 | enum Enum { |
210 | Value1, Value2 |
211 | }; |
212 | |
213 | int fallthrough_covered_enums(Enum e) { |
214 | int n = 0; |
215 | switch (e) { |
216 | default: |
217 | n += 17; |
218 | [[clang::fallthrough]]; // no warning here, this shouldn't be treated as unreachable code |
219 | case Value1: |
220 | n += 19; |
221 | break; |
222 | case Value2: |
223 | n += 21; |
224 | break; |
225 | } |
226 | return n; |
227 | } |
228 | |
229 | // Fallthrough annotations in local classes used to generate "fallthrough |
230 | // annotation does not directly precede switch label" warning. |
231 | void fallthrough_in_local_class() { |
232 | class C { |
233 | void f(int x) { |
234 | switch (x) { |
235 | case 0: |
236 | x++; |
237 | [[clang::fallthrough]]; // no diagnostics |
238 | case 1: |
239 | x++; |
240 | default: // \ |
241 | expected-warning{{unannotated fall-through between switch labels}} \ |
242 | expected-note{{insert 'break;' to avoid fall-through}} |
243 | break; |
244 | } |
245 | } |
246 | }; |
247 | } |
248 | |
249 | // Fallthrough annotations in lambdas used to generate "fallthrough |
250 | // annotation does not directly precede switch label" warning. |
251 | void fallthrough_in_lambda() { |
252 | (void)[] { |
253 | int x = 0; |
254 | switch (x) { |
255 | case 0: |
256 | x++; |
257 | [[clang::fallthrough]]; // no diagnostics |
258 | case 1: |
259 | x++; |
260 | default: // \ |
261 | expected-warning{{unannotated fall-through between switch labels}} \ |
262 | expected-note{{insert 'break;' to avoid fall-through}} |
263 | break; |
264 | } |
265 | }; |
266 | } |
267 | |
268 | namespace PR18983 { |
269 | void fatal() __attribute__((noreturn)); |
270 | int num(); |
271 | void test() { |
272 | switch (num()) { |
273 | case 1: |
274 | fatal(); |
275 | // Don't issue a warning. |
276 | case 2: |
277 | break; |
278 | } |
279 | } |
280 | } |
281 | |
282 | int fallthrough_placement_error(int n) { |
283 | switch (n) { |
284 | [[clang::fallthrough]]; // expected-warning{{fallthrough annotation in unreachable code}} |
285 | n += 300; |
286 | case 221: |
287 | [[clang::fallthrough]]; // expected-error{{fallthrough annotation does not directly precede switch label}} |
288 | return 1; |
289 | case 222: |
290 | [[clang::fallthrough]]; // expected-error{{fallthrough annotation does not directly precede switch label}} |
291 | n += 400; |
292 | [[clang::fallthrough]]; |
293 | case 223: |
294 | [[clang::fallthrough]]; // expected-error{{fallthrough annotation does not directly precede switch label}} |
295 | } |
296 | return n; |
297 | } |
298 | |
299 | int fallthrough_targets(int n) { |
300 | [[clang::fallthrough]]; // expected-error{{fallthrough annotation is outside switch statement}} |
301 | |
302 | [[clang::fallthrough]] // expected-error{{fallthrough attribute is only allowed on empty statements}} |
303 | switch (n) { |
304 | case 121: |
305 | n += 400; |
306 | [[clang::fallthrough]]; // no warning here, correct target |
307 | case 123: |
308 | [[clang::fallthrough]] // expected-error{{fallthrough attribute is only allowed on empty statements}} |
309 | n += 800; |
310 | break; |
311 | [[clang::fallthrough]] // expected-error{{fallthrough attribute is only allowed on empty statements}} expected-note{{did you forget ';'?}} |
312 | case 125: |
313 | n += 1600; |
314 | } |
315 | return n; |
316 | } |
317 | |
318 | int fallthrough_alt_spelling(int n) { |
319 | switch (n) { |
320 | case 0: |
321 | n++; |
322 | [[clang::fallthrough]]; |
323 | case 1: |
324 | n++; |
325 | [[clang::__fallthrough__]]; |
326 | case 2: |
327 | n++; |
328 | break; |
329 | } |
330 | return n; |
331 | } |
332 | |