]>
Commit | Line | Data |
---|---|---|
223e47cc LB |
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 | } |