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