1// RUN: %check_clang_tidy %s hicpp-multiway-paths-covered %t
2
3enum OS { Mac,
4 Windows,
5 Linux };
6
7struct Bitfields {
8 unsigned UInt : 3;
9 int SInt : 1;
10};
11
12int return_integer() { return 42; }
13
14void 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
141void 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
413OS 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.
421void 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.
438void 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

source code of clang-tools-extra/test/clang-tidy/checkers/hicpp/multiway-paths-covered.cpp