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: // 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}}
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       break;
38   }
39   switch (n / 20) {
40     case 7:
41       n += 400;
42       [[clang::fallthrough]];
43     case 9:  // no warning here, intended fall-through marked with an attribute
44       n += 800;
45       [[clang::fallthrough]];
46     default: { // no warning here, intended fall-through marked with an attribute
47       if (n % 2 == 0) {
48         return 1;
49       } else {
50         [[clang::fallthrough]];
51       }
52     }
53     case 10:  // no warning here, intended fall-through marked with an attribute
54       if (n % 3 == 0) {
55         n %= 3;
56       } else {
57         [[clang::fallthrough]];
58       }
59     case 110:  // expected-warning{{unannotated fall-through between switch labels}} but no fix-it hint as we have one fall-through annotation!
60       n += 800;
61   }
62   switch (n / 30) {
63     case 11:
64     case 12:  // no warning here, intended fall-through, no statement between labels
65       n += 1600;
66   }
67   switch (n / 40) {
68     case 13:
69       if (n % 2 == 0) {
70         return 1;
71       } else {
72         return 2;
73       }
74     case 15:  // no warning here, there's no fall-through
75       n += 3200;
76   }
77   switch (n / 50) {
78     case 17: {
79       if (n % 2 == 0) {
80         return 1;
81       } else {
82         return 2;
83       }
84     }
85     case 19: { // no warning here, there's no fall-through
86       n += 6400;
87       return 3;
88     }
89     case 21: { // no warning here, there's no fall-through
90       break;
91     }
92     case 23: // no warning here, there's no fall-through
93       n += 128000;
94       break;
95     case 25: // no warning here, there's no fall-through
96       break;
97   }
98 
99   return n;
100 }
101 
102 class ClassWithDtor {
103 public:
104   ~ClassWithDtor() {}
105 };
106 
107 void fallthrough2(int n) {
108   switch (n) {
109     case 0:
110     {
111       ClassWithDtor temp;
112       break;
113     }
114     default: // no warning here, there's no fall-through
115       break;
116   }
117 }
118 
119 #define MY_SWITCH(X, Y, Z, U, V) switch (X) { case Y: Z; case U: V; }
120 #define MY_SWITCH2(X, Y, Z) switch (X) { Y; Z; }
121 #define MY_CASE(X, Y) case X: Y
122 #define MY_CASE2(X, Y, U, V) case X: Y; case U: V
123 
124 int fallthrough_macro1(int n) {
125   MY_SWITCH(n, 13, n *= 2, 14, break)  // expected-warning{{unannotated fall-through between switch labels}}
126 
127   switch (n + 1) {
128     MY_CASE(33, n += 2);
129     MY_CASE(44, break);  // expected-warning{{unannotated fall-through between switch labels}}
130     MY_CASE(55, n += 3);
131   }
132 
133   switch (n + 3) {
134     MY_CASE(333, return 333);
135     MY_CASE2(444, n += 44, 4444, break);  // expected-warning{{unannotated fall-through between switch labels}}
136     MY_CASE(555, n += 33);
137   }
138 
139   MY_SWITCH2(n + 4, MY_CASE(17, n *= 3), MY_CASE(19, break))  // expected-warning{{unannotated fall-through between switch labels}}
140 
141   MY_SWITCH2(n + 5, MY_CASE(21, break), MY_CASE2(23, n *= 7, 25, break))  // expected-warning{{unannotated fall-through between switch labels}}
142 
143   return n;
144 }
145 
146 int fallthrough_position(int n) {
147   switch (n) {
148       [[clang::fallthrough]];  // expected-warning{{fallthrough annotation in unreachable code}}
149     case 221:
150       [[clang::fallthrough]]; // expected-warning{{fallthrough annotation does not directly precede switch label}}
151       return 1;
152       [[clang::fallthrough]];  // expected-warning{{fallthrough annotation in unreachable code}}
153     case 222:
154       [[clang::fallthrough]]; // expected-warning{{fallthrough annotation does not directly precede switch label}}
155       n += 400;
156     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}}
157       [[clang::fallthrough]]; // expected-warning{{fallthrough annotation does not directly precede switch label}}
158   }
159 
160   // TODO: uncomment this test after CFG gets more options to deal with
161   // unreachable code:
162   // http://lists.cs.uiuc.edu/pipermail/cfe-commits/Week-of-Mon-20120507/057370.html
163 #if 0
164   long p = static_cast<long>(n) * n;
165   switch (sizeof(p)) {
166     case 9:                    // this test will not work on compilers with 72-bit long
167       n += static_cast<int>(p >> 32);
168       [[clang::fallthrough]];  // no warning here
169     case 5:                    // it is not intended to work on compilers with 40-bit long as well
170       n += static_cast<int>(p);
171       break;
172     default:
173      break;
174   }
175 #endif
176 
177   return n;
178 }
179 
180 int fallthrough_targets(int n) {
181   [[clang::fallthrough]]; // expected-error{{fallthrough annotation is outside switch statement}}
182 
183   [[clang::fallthrough]]  // expected-error{{fallthrough attribute is only allowed on empty statements}}
184   switch (n) {
185     case 121:
186       n += 400;
187       [[clang::fallthrough]]; // no warning here, correct target
188     case 123:
189       [[clang::fallthrough]]  // expected-error{{fallthrough attribute is only allowed on empty statements}}
190       n += 800;
191       break;
192     [[clang::fallthrough]]    // expected-error{{fallthrough attribute is only allowed on empty statements}} expected-note{{did you forget ';'?}}
193     case 125:
194       n += 1600;
195   }
196   return n;
197 }
198