blob: d7959238c6b3612919432746df03295047767bd5 [file] [log] [blame]
Richard Smithe0d3b4c2012-05-03 18:27:39 +00001// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 -Wimplicit-fallthrough %s
2
3
4int 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 }
Alexander Kornienko4874a812013-01-30 03:49:44 +000013 case -1: // no warning here, ignore fall-through from unreachable code
Richard Smithe0d3b4c2012-05-03 18:27:39 +000014 ;
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;
Alexander Kornienkoa189d892012-05-26 00:49:15 +000036 case 66: // expected-warning{{unannotated fall-through between switch labels}} expected-note{{insert 'break;' to avoid fall-through}}
Alexander Kornienkoe992ed12013-01-25 15:49:34 +000037 case 67:
38 case 68:
Alexander Kornienkoa189d892012-05-26 00:49:15 +000039 break;
Richard Smithe0d3b4c2012-05-03 18:27:39 +000040 }
Alexander Kornienkoc6dcea92013-01-25 20:44:56 +000041 switch (n / 15) {
Alexander Kornienko4874a812013-01-30 03:49:44 +000042label_default:
43 default:
Alexander Kornienkoc6dcea92013-01-25 20:44:56 +000044 n += 333;
Alexander Kornienko4874a812013-01-30 03:49:44 +000045 if (n % 10)
46 goto label_default;
Alexander Kornienkoc6dcea92013-01-25 20:44:56 +000047 break;
Alexander Kornienko4874a812013-01-30 03:49:44 +000048 case 70:
Alexander Kornienkoc6dcea92013-01-25 20:44:56 +000049 n += 335;
50 break;
51 }
Richard Smithe0d3b4c2012-05-03 18:27:39 +000052 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
115class ClassWithDtor {
116public:
117 ~ClassWithDtor() {}
118};
119
120void 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
Alexander Kornienko4874a812013-01-30 03:49:44 +0000132void 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
Richard Smithe0d3b4c2012-05-03 18:27:39 +0000148#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
153int 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
Alexander Kornienko0162b832013-02-01 15:39:20 +0000175void fallthrough_cfgblock_with_null_successor(int x) {
176 (x && "") ? (void)(0) : (void)(1);
177 switch (x) {}
178}
179
Richard Smithe0d3b4c2012-05-03 18:27:39 +0000180int fallthrough_position(int n) {
181 switch (n) {
Alexander Kornienko878d0ad2013-02-07 02:17:19 +0000182 [[clang::fallthrough]]; // expected-warning{{fallthrough annotation does not directly precede switch label}}
183 n += 300;
Richard Smithe0d3b4c2012-05-03 18:27:39 +0000184 [[clang::fallthrough]]; // expected-warning{{fallthrough annotation in unreachable code}}
185 case 221:
Alexander Kornienko878d0ad2013-02-07 02:17:19 +0000186 [[clang::fallthrough]]; // expected-warning{{fallthrough annotation does not directly precede switch label}}
Richard Smithe0d3b4c2012-05-03 18:27:39 +0000187 return 1;
188 [[clang::fallthrough]]; // expected-warning{{fallthrough annotation in unreachable code}}
189 case 222:
Alexander Kornienko878d0ad2013-02-07 02:17:19 +0000190 [[clang::fallthrough]]; // expected-warning{{fallthrough annotation does not directly precede switch label}}
Richard Smithe0d3b4c2012-05-03 18:27:39 +0000191 n += 400;
192 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}}
193 [[clang::fallthrough]]; // expected-warning{{fallthrough annotation does not directly precede switch label}}
194 }
Alexander Kornienko86197b32012-06-20 21:12:23 +0000195
Alexander Kornienko86197b32012-06-20 21:12:23 +0000196 long p = static_cast<long>(n) * n;
197 switch (sizeof(p)) {
Alexander Kornienko878d0ad2013-02-07 02:17:19 +0000198 case 9:
Alexander Kornienko86197b32012-06-20 21:12:23 +0000199 n += static_cast<int>(p >> 32);
200 [[clang::fallthrough]]; // no warning here
Alexander Kornienko878d0ad2013-02-07 02:17:19 +0000201 case 5:
Alexander Kornienko86197b32012-06-20 21:12:23 +0000202 n += static_cast<int>(p);
Alexander Kornienko878d0ad2013-02-07 02:17:19 +0000203 [[clang::fallthrough]]; // no warning here
Alexander Kornienko86197b32012-06-20 21:12:23 +0000204 default:
Alexander Kornienko878d0ad2013-02-07 02:17:19 +0000205 n += 1;
206 break;
Alexander Kornienko86197b32012-06-20 21:12:23 +0000207 }
Alexander Kornienko86197b32012-06-20 21:12:23 +0000208
Richard Smithe0d3b4c2012-05-03 18:27:39 +0000209 return n;
210}
211
Alexander Kornienko878d0ad2013-02-07 02:17:19 +0000212enum Enum {
213 Value1, Value2
214};
215
216int fallthrough_covered_enums(Enum e) {
217 int n = 0;
218 switch (e) {
219 default:
220 n += 17;
221 [[clang::fallthrough]]; // no warning here, this shouldn't be treated as unreachable code
222 case Value1:
223 n += 19;
224 break;
225 case Value2:
226 n += 21;
227 break;
228 }
229 return n;
230}
231
Richard Smithe0d3b4c2012-05-03 18:27:39 +0000232int fallthrough_targets(int n) {
233 [[clang::fallthrough]]; // expected-error{{fallthrough annotation is outside switch statement}}
234
235 [[clang::fallthrough]] // expected-error{{fallthrough attribute is only allowed on empty statements}}
236 switch (n) {
237 case 121:
238 n += 400;
239 [[clang::fallthrough]]; // no warning here, correct target
240 case 123:
241 [[clang::fallthrough]] // expected-error{{fallthrough attribute is only allowed on empty statements}}
242 n += 800;
243 break;
244 [[clang::fallthrough]] // expected-error{{fallthrough attribute is only allowed on empty statements}} expected-note{{did you forget ';'?}}
245 case 125:
246 n += 1600;
247 }
248 return n;
249}
Alexander Kornienko8b0822b2013-04-02 17:55:01 +0000250
251// Fallthrough annotations in local classes used to generate "fallthrough
252// annotation does not directly precede switch label" warning.
253void fallthrough_in_local_class() {
254 class C {
255 void f(int x) {
256 switch (x) {
257 case 0:
258 x++;
259 [[clang::fallthrough]]; // no diagnostics
260 case 1:
261 x++;
262 break;
263 }
264 }
265 };
266}
267