Richard Smith | e0d3b4c | 2012-05-03 18:27:39 +0000 | [diff] [blame] | 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 | } |
Alexander Kornienko | 4874a81 | 2013-01-30 03:49:44 +0000 | [diff] [blame] | 13 | case -1: // no warning here, ignore fall-through from unreachable code |
Richard Smith | e0d3b4c | 2012-05-03 18:27:39 +0000 | [diff] [blame] | 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; |
Alexander Kornienko | a189d89 | 2012-05-26 00:49:15 +0000 | [diff] [blame] | 36 | case 66: // expected-warning{{unannotated fall-through between switch labels}} expected-note{{insert 'break;' to avoid fall-through}} |
Alexander Kornienko | e992ed1 | 2013-01-25 15:49:34 +0000 | [diff] [blame] | 37 | case 67: |
| 38 | case 68: |
Alexander Kornienko | a189d89 | 2012-05-26 00:49:15 +0000 | [diff] [blame] | 39 | break; |
Richard Smith | e0d3b4c | 2012-05-03 18:27:39 +0000 | [diff] [blame] | 40 | } |
Alexander Kornienko | c6dcea9 | 2013-01-25 20:44:56 +0000 | [diff] [blame] | 41 | switch (n / 15) { |
Alexander Kornienko | 4874a81 | 2013-01-30 03:49:44 +0000 | [diff] [blame] | 42 | label_default: |
| 43 | default: |
Alexander Kornienko | c6dcea9 | 2013-01-25 20:44:56 +0000 | [diff] [blame] | 44 | n += 333; |
Alexander Kornienko | 4874a81 | 2013-01-30 03:49:44 +0000 | [diff] [blame] | 45 | if (n % 10) |
| 46 | goto label_default; |
Alexander Kornienko | c6dcea9 | 2013-01-25 20:44:56 +0000 | [diff] [blame] | 47 | break; |
Alexander Kornienko | 4874a81 | 2013-01-30 03:49:44 +0000 | [diff] [blame] | 48 | case 70: |
Alexander Kornienko | c6dcea9 | 2013-01-25 20:44:56 +0000 | [diff] [blame] | 49 | n += 335; |
| 50 | break; |
| 51 | } |
Richard Smith | e0d3b4c | 2012-05-03 18:27:39 +0000 | [diff] [blame] | 52 | 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 | |
| 115 | class ClassWithDtor { |
| 116 | public: |
| 117 | ~ClassWithDtor() {} |
| 118 | }; |
| 119 | |
| 120 | void 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 Kornienko | 4874a81 | 2013-01-30 03:49:44 +0000 | [diff] [blame] | 132 | void 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 Smith | e0d3b4c | 2012-05-03 18:27:39 +0000 | [diff] [blame] | 148 | #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 | |
| 153 | int 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 Kornienko | 0162b83 | 2013-02-01 15:39:20 +0000 | [diff] [blame] | 175 | void fallthrough_cfgblock_with_null_successor(int x) { |
| 176 | (x && "") ? (void)(0) : (void)(1); |
| 177 | switch (x) {} |
| 178 | } |
| 179 | |
Richard Smith | e0d3b4c | 2012-05-03 18:27:39 +0000 | [diff] [blame] | 180 | int fallthrough_position(int n) { |
| 181 | switch (n) { |
Alexander Kornienko | 878d0ad | 2013-02-07 02:17:19 +0000 | [diff] [blame] | 182 | [[clang::fallthrough]]; // expected-warning{{fallthrough annotation does not directly precede switch label}} |
| 183 | n += 300; |
Richard Smith | e0d3b4c | 2012-05-03 18:27:39 +0000 | [diff] [blame] | 184 | [[clang::fallthrough]]; // expected-warning{{fallthrough annotation in unreachable code}} |
| 185 | case 221: |
Alexander Kornienko | 878d0ad | 2013-02-07 02:17:19 +0000 | [diff] [blame] | 186 | [[clang::fallthrough]]; // expected-warning{{fallthrough annotation does not directly precede switch label}} |
Richard Smith | e0d3b4c | 2012-05-03 18:27:39 +0000 | [diff] [blame] | 187 | return 1; |
| 188 | [[clang::fallthrough]]; // expected-warning{{fallthrough annotation in unreachable code}} |
| 189 | case 222: |
Alexander Kornienko | 878d0ad | 2013-02-07 02:17:19 +0000 | [diff] [blame] | 190 | [[clang::fallthrough]]; // expected-warning{{fallthrough annotation does not directly precede switch label}} |
Richard Smith | e0d3b4c | 2012-05-03 18:27:39 +0000 | [diff] [blame] | 191 | 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 Kornienko | 86197b3 | 2012-06-20 21:12:23 +0000 | [diff] [blame] | 195 | |
Alexander Kornienko | 86197b3 | 2012-06-20 21:12:23 +0000 | [diff] [blame] | 196 | long p = static_cast<long>(n) * n; |
| 197 | switch (sizeof(p)) { |
Alexander Kornienko | 878d0ad | 2013-02-07 02:17:19 +0000 | [diff] [blame] | 198 | case 9: |
Alexander Kornienko | 86197b3 | 2012-06-20 21:12:23 +0000 | [diff] [blame] | 199 | n += static_cast<int>(p >> 32); |
| 200 | [[clang::fallthrough]]; // no warning here |
Alexander Kornienko | 878d0ad | 2013-02-07 02:17:19 +0000 | [diff] [blame] | 201 | case 5: |
Alexander Kornienko | 86197b3 | 2012-06-20 21:12:23 +0000 | [diff] [blame] | 202 | n += static_cast<int>(p); |
Alexander Kornienko | 878d0ad | 2013-02-07 02:17:19 +0000 | [diff] [blame] | 203 | [[clang::fallthrough]]; // no warning here |
Alexander Kornienko | 86197b3 | 2012-06-20 21:12:23 +0000 | [diff] [blame] | 204 | default: |
Alexander Kornienko | 878d0ad | 2013-02-07 02:17:19 +0000 | [diff] [blame] | 205 | n += 1; |
| 206 | break; |
Alexander Kornienko | 86197b3 | 2012-06-20 21:12:23 +0000 | [diff] [blame] | 207 | } |
Alexander Kornienko | 86197b3 | 2012-06-20 21:12:23 +0000 | [diff] [blame] | 208 | |
Richard Smith | e0d3b4c | 2012-05-03 18:27:39 +0000 | [diff] [blame] | 209 | return n; |
| 210 | } |
| 211 | |
Alexander Kornienko | 878d0ad | 2013-02-07 02:17:19 +0000 | [diff] [blame] | 212 | enum Enum { |
| 213 | Value1, Value2 |
| 214 | }; |
| 215 | |
| 216 | int 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 | |
Stephen Hines | c568f1e | 2014-07-21 00:47:37 -0700 | [diff] [blame] | 232 | // Fallthrough annotations in local classes used to generate "fallthrough |
| 233 | // annotation does not directly precede switch label" warning. |
| 234 | void fallthrough_in_local_class() { |
| 235 | class C { |
| 236 | void f(int x) { |
| 237 | switch (x) { |
| 238 | case 0: |
| 239 | x++; |
| 240 | [[clang::fallthrough]]; // no diagnostics |
| 241 | case 1: |
| 242 | x++; |
| 243 | default: // \ |
| 244 | expected-warning{{unannotated fall-through between switch labels}} \ |
| 245 | expected-note{{insert 'break;' to avoid fall-through}} |
| 246 | break; |
| 247 | } |
| 248 | } |
| 249 | }; |
| 250 | } |
| 251 | |
| 252 | // Fallthrough annotations in lambdas used to generate "fallthrough |
| 253 | // annotation does not directly precede switch label" warning. |
| 254 | void fallthrough_in_lambda() { |
| 255 | (void)[] { |
| 256 | int x = 0; |
| 257 | switch (x) { |
| 258 | case 0: |
| 259 | x++; |
| 260 | [[clang::fallthrough]]; // no diagnostics |
| 261 | case 1: |
| 262 | x++; |
| 263 | default: // \ |
| 264 | expected-warning{{unannotated fall-through between switch labels}} \ |
| 265 | expected-note{{insert 'break;' to avoid fall-through}} |
| 266 | break; |
| 267 | } |
| 268 | }; |
| 269 | } |
| 270 | |
| 271 | namespace PR18983 { |
| 272 | void fatal() __attribute__((noreturn)); |
| 273 | int num(); |
| 274 | void test() { |
| 275 | switch (num()) { |
| 276 | case 1: |
| 277 | fatal(); |
| 278 | // Don't issue a warning. |
| 279 | case 2: |
| 280 | break; |
| 281 | } |
| 282 | } |
| 283 | } |
| 284 | |
Richard Smith | e0d3b4c | 2012-05-03 18:27:39 +0000 | [diff] [blame] | 285 | int fallthrough_targets(int n) { |
| 286 | [[clang::fallthrough]]; // expected-error{{fallthrough annotation is outside switch statement}} |
| 287 | |
| 288 | [[clang::fallthrough]] // expected-error{{fallthrough attribute is only allowed on empty statements}} |
| 289 | switch (n) { |
| 290 | case 121: |
| 291 | n += 400; |
| 292 | [[clang::fallthrough]]; // no warning here, correct target |
| 293 | case 123: |
| 294 | [[clang::fallthrough]] // expected-error{{fallthrough attribute is only allowed on empty statements}} |
| 295 | n += 800; |
| 296 | break; |
| 297 | [[clang::fallthrough]] // expected-error{{fallthrough attribute is only allowed on empty statements}} expected-note{{did you forget ';'?}} |
| 298 | case 125: |
| 299 | n += 1600; |
| 300 | } |
| 301 | return n; |
| 302 | } |