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