1 // RUN: %check_clang_tidy %s hicpp-multiway-paths-covered %t
2 
3 enum OS { Mac,
4           Windows,
5           Linux };
6 
7 struct Bitfields {
8   unsigned UInt : 3;
9   int SInt : 1;
10 };
11 
return_integer()12 int return_integer() { return 42; }
13 
bad_switch(int i)14 void bad_switch(int i) {
15   switch (i) {
16     // CHECK-MESSAGES: [[@LINE-1]]:3: warning: switch with only one case; use an if statement
17   case 0:
18     break;
19   }
20   // No default in this switch
21   switch (i) {
22   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: potential uncovered code path; add a default label
23   case 0:
24     break;
25   case 1:
26     break;
27   case 2:
28     break;
29   }
30 
31   // degenerate, maybe even warning
32   switch (i) {
33     // CHECK-MESSAGES: [[@LINE-1]]:3: warning: switch statement without labels has no effect
34   }
35 
36   switch (int j = return_integer()) {
37   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: potential uncovered code path; add a default label
38   case 0:
39   case 1:
40   case 2:
41     break;
42   }
43 
44   // Degenerated, only default case.
45   switch (i) {
46     // CHECK-MESSAGES: [[@LINE-1]]:3: warning: degenerated switch with default label only
47   default:
48     break;
49   }
50 
51   // Degenerated, only one case label and default case -> Better as if-stmt.
52   switch (i) {
53     // CHECK-MESSAGES: [[@LINE-1]]:3: warning: switch could be better written as an if/else statement
54   case 0:
55     break;
56   default:
57     break;
58   }
59 
60   unsigned long long BigNumber = 0;
61   switch (BigNumber) {
62   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: potential uncovered code path; add a default label
63   case 0:
64   case 1:
65     break;
66   }
67 
68   const int &IntRef = i;
69   switch (IntRef) {
70   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: potential uncovered code path; add a default label
71   case 0:
72   case 1:
73     break;
74   }
75 
76   char C = 'A';
77   switch (C) {
78   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: potential uncovered code path; add a default label
79   case 'A':
80     break;
81   case 'B':
82     break;
83   }
84 
85   Bitfields Bf;
86   // UInt has 3 bits size.
87   switch (Bf.UInt) {
88     // CHECK-MESSAGES: [[@LINE-1]]:3: warning: potential uncovered code path; add a default label
89   case 0:
90   case 1:
91     break;
92   }
93   // All paths explicitly covered.
94   switch (Bf.UInt) {
95   case 0:
96   case 1:
97   case 2:
98   case 3:
99   case 4:
100   case 5:
101   case 6:
102   case 7:
103     break;
104   }
105   // SInt has 1 bit size, so this is somewhat degenerated.
106   switch (Bf.SInt) {
107     // CHECK-MESSAGES: [[@LINE-1]]:3: warning: switch with only one case; use an if statement
108   case 0:
109     break;
110   }
111   // All paths explicitly covered.
112   switch (Bf.SInt) {
113   case 0:
114   case 1:
115     break;
116   }
117 
118   bool Flag = false;
119   switch (Flag) {
120     // CHECK-MESSAGES:[[@LINE-1]]:3: warning: switch with only one case; use an if statement
121   case true:
122     break;
123   }
124 
125   switch (Flag) {
126     // CHECK-MESSAGES: [[@LINE-1]]:3: warning: degenerated switch with default label only
127   default:
128     break;
129   }
130 
131   // This `switch` will create a frontend warning from '-Wswitch-bool' but is
132   // ok for this check.
133   switch (Flag) {
134   case true:
135     break;
136   case false:
137     break;
138   }
139 }
140 
unproblematic_switch(unsigned char c)141 void unproblematic_switch(unsigned char c) {
142   //
143   switch (c) {
144   case 0:
145   case 1:
146   case 2:
147   case 3:
148   case 4:
149   case 5:
150   case 6:
151   case 7:
152   case 8:
153   case 9:
154   case 10:
155   case 11:
156   case 12:
157   case 13:
158   case 14:
159   case 15:
160   case 16:
161   case 17:
162   case 18:
163   case 19:
164   case 20:
165   case 21:
166   case 22:
167   case 23:
168   case 24:
169   case 25:
170   case 26:
171   case 27:
172   case 28:
173   case 29:
174   case 30:
175   case 31:
176   case 32:
177   case 33:
178   case 34:
179   case 35:
180   case 36:
181   case 37:
182   case 38:
183   case 39:
184   case 40:
185   case 41:
186   case 42:
187   case 43:
188   case 44:
189   case 45:
190   case 46:
191   case 47:
192   case 48:
193   case 49:
194   case 50:
195   case 51:
196   case 52:
197   case 53:
198   case 54:
199   case 55:
200   case 56:
201   case 57:
202   case 58:
203   case 59:
204   case 60:
205   case 61:
206   case 62:
207   case 63:
208   case 64:
209   case 65:
210   case 66:
211   case 67:
212   case 68:
213   case 69:
214   case 70:
215   case 71:
216   case 72:
217   case 73:
218   case 74:
219   case 75:
220   case 76:
221   case 77:
222   case 78:
223   case 79:
224   case 80:
225   case 81:
226   case 82:
227   case 83:
228   case 84:
229   case 85:
230   case 86:
231   case 87:
232   case 88:
233   case 89:
234   case 90:
235   case 91:
236   case 92:
237   case 93:
238   case 94:
239   case 95:
240   case 96:
241   case 97:
242   case 98:
243   case 99:
244   case 100:
245   case 101:
246   case 102:
247   case 103:
248   case 104:
249   case 105:
250   case 106:
251   case 107:
252   case 108:
253   case 109:
254   case 110:
255   case 111:
256   case 112:
257   case 113:
258   case 114:
259   case 115:
260   case 116:
261   case 117:
262   case 118:
263   case 119:
264   case 120:
265   case 121:
266   case 122:
267   case 123:
268   case 124:
269   case 125:
270   case 126:
271   case 127:
272   case 128:
273   case 129:
274   case 130:
275   case 131:
276   case 132:
277   case 133:
278   case 134:
279   case 135:
280   case 136:
281   case 137:
282   case 138:
283   case 139:
284   case 140:
285   case 141:
286   case 142:
287   case 143:
288   case 144:
289   case 145:
290   case 146:
291   case 147:
292   case 148:
293   case 149:
294   case 150:
295   case 151:
296   case 152:
297   case 153:
298   case 154:
299   case 155:
300   case 156:
301   case 157:
302   case 158:
303   case 159:
304   case 160:
305   case 161:
306   case 162:
307   case 163:
308   case 164:
309   case 165:
310   case 166:
311   case 167:
312   case 168:
313   case 169:
314   case 170:
315   case 171:
316   case 172:
317   case 173:
318   case 174:
319   case 175:
320   case 176:
321   case 177:
322   case 178:
323   case 179:
324   case 180:
325   case 181:
326   case 182:
327   case 183:
328   case 184:
329   case 185:
330   case 186:
331   case 187:
332   case 188:
333   case 189:
334   case 190:
335   case 191:
336   case 192:
337   case 193:
338   case 194:
339   case 195:
340   case 196:
341   case 197:
342   case 198:
343   case 199:
344   case 200:
345   case 201:
346   case 202:
347   case 203:
348   case 204:
349   case 205:
350   case 206:
351   case 207:
352   case 208:
353   case 209:
354   case 210:
355   case 211:
356   case 212:
357   case 213:
358   case 214:
359   case 215:
360   case 216:
361   case 217:
362   case 218:
363   case 219:
364   case 220:
365   case 221:
366   case 222:
367   case 223:
368   case 224:
369   case 225:
370   case 226:
371   case 227:
372   case 228:
373   case 229:
374   case 230:
375   case 231:
376   case 232:
377   case 233:
378   case 234:
379   case 235:
380   case 236:
381   case 237:
382   case 238:
383   case 239:
384   case 240:
385   case 241:
386   case 242:
387   case 243:
388   case 244:
389   case 245:
390   case 246:
391   case 247:
392   case 248:
393   case 249:
394   case 250:
395   case 251:
396   case 252:
397   case 253:
398   case 254:
399   case 255:
400     break;
401   }
402 
403   // Some paths are covered by the switch and a default case is present.
404   switch (c) {
405   case 1:
406   case 2:
407   case 3:
408   default:
409     break;
410   }
411 }
412 
return_enumerator()413 OS return_enumerator() {
414   return Linux;
415 }
416 
417 // Enumpaths are already covered by a warning, this is just to ensure, that there is
418 // no interference or false positives.
419 // -Wswitch warns about uncovered enum paths and each here described case is already
420 // covered.
switch_enums(OS os)421 void switch_enums(OS os) {
422   switch (os) {
423   case Linux:
424     break;
425   }
426 
427   switch (OS another_os = return_enumerator()) {
428   case Linux:
429     break;
430   }
431 
432   switch (os) {
433   }
434 }
435 
436 /// All of these cases will not emit a warning per default, but with explicit activation.
437 /// Covered in extra test file.
problematic_if(int i,enum OS os)438 void problematic_if(int i, enum OS os) {
439   if (i > 0) {
440     return;
441   } else if (i < 0) {
442     return;
443   }
444 
445   if (os == Mac) {
446     return;
447   } else if (os == Linux) {
448     if (true) {
449       return;
450     } else if (false) {
451       return;
452     }
453     return;
454   } else {
455     /* unreachable */
456     if (true) // check if the parent would match here as well
457       return;
458   }
459 
460   // Ok, because all paths are covered
461   if (i > 0) {
462     return;
463   } else if (i < 0) {
464     return;
465   } else {
466     /* error, maybe precondition failed */
467   }
468 }
469