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