msg_193.c revision 1.16 1 /* $NetBSD: msg_193.c,v 1.16 2022/01/15 23:21:34 rillig Exp $ */
2 # 3 "msg_193.c"
3
4 // Test for message: statement not reached [193]
5
6 /*
7 * Test the reachability of statements in a function.
8 *
9 * if
10 * if-else
11 * if-else-if-else
12 * for
13 * while
14 * do-while
15 * switch
16 * break
17 * continue
18 * goto
19 * return
20 *
21 * constant expression
22 * system-dependent constant expression
23 */
24
25 extern void reachable(void);
26 extern void unreachable(void);
27 extern _Bool maybe(void);
28
29
30 void
31 test_statement(void)
32 {
33 reachable();
34 reachable();
35 }
36
37 void
38 test_compound_statement(void)
39 {
40 reachable();
41 {
42 reachable();
43 reachable();
44 }
45 reachable();
46 }
47
48 void
49 test_if_statement(void)
50 {
51 if (1)
52 reachable();
53 reachable();
54 if (0)
55 unreachable(); /* expect: 193 */
56 reachable();
57 }
58
59 void
60 test_if_compound_statement(void)
61 {
62 if (1) {
63 reachable();
64 }
65 if (1) {
66 {
67 {
68 reachable();
69 }
70 }
71 }
72
73 if (0) {
74 unreachable(); /* expect: 193 */
75 }
76 if (0) {
77 {
78 {
79 unreachable(); /* expect: 193 */
80 }
81 }
82 }
83 }
84
85 void
86 test_if_without_else(void)
87 {
88 if (1)
89 reachable();
90 reachable();
91
92 if (0)
93 unreachable(); /* expect: 193 */
94 reachable();
95 }
96
97 void
98 test_if_with_else(void)
99 {
100 if (1)
101 reachable();
102 else
103 unreachable(); /* expect: 193 */
104 reachable();
105
106 if (0)
107 unreachable(); /* expect: 193 */
108 else
109 reachable();
110 reachable();
111 }
112
113 void
114 test_if_else_if_else(void)
115 {
116 if (1)
117 reachable();
118 else if (1) /* expect: 193 */
119 unreachable();
120 else
121 unreachable(); /* expect: 193 */
122
123 if (0)
124 unreachable(); /* expect: 193 */
125 else if (1)
126 reachable();
127 else
128 unreachable(); /* expect: 193 */
129
130 if (0)
131 unreachable(); /* expect: 193 */
132 else if (0)
133 unreachable(); /* expect: 193 */
134 else
135 reachable();
136 }
137
138 void
139 test_if_return(void)
140 {
141 if (1)
142 return;
143 unreachable(); /* expect: 193 */
144 }
145
146 void
147 test_if_else_return(void)
148 {
149 if (1)
150 reachable();
151 else
152 return; /* expect: 193 */
153 reachable();
154 }
155
156 void
157 test_for_forever(void)
158 {
159 for (;;)
160 reachable();
161 unreachable(); /* expect: 193 */
162 }
163
164 void
165 test_for_true(void)
166 {
167 for (; 1;)
168 reachable();
169 unreachable(); /* expect: 193 */
170 }
171
172 void
173 test_for_false(void)
174 {
175 for (; 0;)
176 unreachable(); /* expect: 193 */
177 reachable();
178 }
179
180 void
181 test_for_break(void)
182 {
183 for (;;) {
184 reachable();
185 break;
186 unreachable(); /* expect: 193 */
187 }
188 reachable();
189 }
190
191 void
192 test_for_if_break(void)
193 {
194 for (;;) {
195 reachable();
196 if (0) {
197 unreachable(); /* expect: 193 */
198 break;
199 unreachable(); /* expect: 193 */
200 }
201 if (1) {
202 reachable();
203 break;
204 unreachable(); /* expect: 193 */
205 }
206 unreachable(); /* expect: 193 */
207 }
208 reachable();
209 }
210
211 void
212 test_for_continue(void)
213 {
214 for (;;) {
215 reachable();
216 continue;
217 unreachable(); /* expect: 193 */
218 }
219 unreachable(); /* expect: 193 */
220 }
221
222 void
223 test_for_if_continue(void)
224 {
225 for (;;) {
226 reachable();
227 if (0) {
228 unreachable(); /* expect: 193 */
229 continue;
230 unreachable(); /* expect: 193 */
231 }
232 if (1) {
233 reachable();
234 continue;
235 unreachable(); /* expect: 193 */
236 }
237 unreachable(); /* expect: 193 */
238 }
239 unreachable(); /* expect: 193 */
240 }
241
242 void
243 test_for_return(void)
244 {
245 for (;;) {
246 reachable();
247 return;
248 unreachable(); /* expect: 193 */
249 }
250 unreachable(); /* expect: 193 */
251 }
252
253 void
254 test_for_if_return(void)
255 {
256 for (;;) {
257 reachable();
258 if (0) {
259 unreachable(); /* expect: 193 */
260 return;
261 unreachable(); /* expect: 193 */
262 }
263 if (1) {
264 reachable();
265 return;
266 unreachable(); /* expect: 193 */
267 }
268 unreachable(); /* expect: 193 */
269 }
270 unreachable(); /* expect: 193 */
271 }
272
273 void
274 test_while_true(void)
275 {
276 while (1)
277 reachable();
278 unreachable(); /* expect: 193 */
279 }
280
281 void
282 test_while_false(void)
283 {
284 while (0)
285 unreachable(); /* expect: 193 */
286 reachable();
287 }
288
289 void
290 test_while_break(void)
291 {
292 while (1) {
293 reachable();
294 break;
295 unreachable(); /* expect: 193 */
296 }
297 reachable();
298 }
299
300 void
301 test_while_if_break(void)
302 {
303 while (1) {
304 reachable();
305 if (0) {
306 unreachable(); /* expect: 193 */
307 break;
308 unreachable(); /* expect: 193 */
309 }
310 if (1) {
311 reachable();
312 break;
313 unreachable(); /* expect: 193 */
314 }
315 unreachable(); /* expect: 193 */
316 }
317 reachable();
318 }
319
320 void
321 test_while_continue(void)
322 {
323 while (1) {
324 reachable();
325 continue;
326 unreachable(); /* expect: 193 */
327 }
328 unreachable(); /* expect: 193 */
329 }
330
331 void
332 test_while_if_continue(void)
333 {
334 while (1) {
335 reachable();
336 if (0) {
337 unreachable(); /* expect: 193 */
338 continue;
339 unreachable(); /* expect: 193 */
340 }
341 if (1) {
342 reachable();
343 continue;
344 unreachable(); /* expect: 193 */
345 }
346 unreachable(); /* expect: 193 */
347 }
348 unreachable(); /* expect: 193 */
349 }
350
351 void
352 test_while_return(void)
353 {
354 while (1) {
355 reachable();
356 return;
357 unreachable(); /* expect: 193 */
358 }
359 unreachable(); /* expect: 193 */
360 }
361
362 void
363 test_while_if_return(void)
364 {
365 while (1) {
366 reachable();
367 if (0) {
368 unreachable(); /* expect: 193 */
369 return;
370 unreachable(); /* expect: 193 */
371 }
372 if (1) {
373 reachable();
374 return;
375 unreachable(); /* expect: 193 */
376 }
377 unreachable(); /* expect: 193 */
378 }
379 unreachable(); /* expect: 193 */
380 }
381
382 void
383 test_do_while_true(void)
384 {
385 do {
386 reachable();
387 } while (1);
388 unreachable(); /* expect: 193 */
389 }
390
391 void
392 test_do_while_false(void)
393 {
394 do {
395 reachable();
396 } while (0);
397 reachable();
398 }
399
400 void
401 test_do_while_break(void)
402 {
403 do {
404 reachable();
405 break;
406 unreachable(); /* expect: 193 */
407 } while (1);
408 reachable();
409 }
410
411 void
412 test_do_while_if_break(void)
413 {
414 do {
415 reachable();
416 if (0) {
417 unreachable(); /* expect: 193 */
418 break;
419 unreachable(); /* expect: 193 */
420 }
421 if (1) {
422 reachable();
423 break;
424 unreachable(); /* expect: 193 */
425 }
426 unreachable(); /* expect: 193 */
427 } while (1);
428 reachable();
429 }
430
431 void
432 test_do_while_continue(void)
433 {
434 do {
435 reachable();
436 continue;
437 unreachable(); /* expect: 193 */
438 } while (1);
439 unreachable(); /* expect: 193 */
440 }
441
442 void
443 test_do_while_if_continue(void)
444 {
445 do {
446 reachable();
447 if (0) {
448 unreachable(); /* expect: 193 */
449 continue;
450 unreachable(); /* expect: 193 */
451 }
452 if (1) {
453 reachable();
454 continue;
455 unreachable(); /* expect: 193 */
456 }
457 unreachable(); /* expect: 193 */
458 } while (1);
459 unreachable(); /* expect: 193 */
460 }
461
462 void
463 test_do_while_return(void)
464 {
465 do {
466 reachable();
467 return;
468 unreachable(); /* expect: 193 */
469 } while (1);
470 unreachable(); /* expect: 193 */
471 }
472
473 void
474 test_do_while_if_return(void)
475 {
476 do {
477 reachable();
478 if (0) {
479 unreachable(); /* expect: 193 */
480 return;
481 unreachable(); /* expect: 193 */
482 }
483 if (1) {
484 reachable();
485 return;
486 unreachable(); /* expect: 193 */
487 }
488 unreachable(); /* expect: 193 */
489 } while (1);
490 unreachable(); /* expect: 193 */
491 }
492
493 void
494 test_if_nested(void)
495 {
496 if (0) {
497 if (1) /* expect: 193 */
498 unreachable();
499 else
500 unreachable(); /* expect: 193 *//* XXX: redundant */
501
502 if (0)
503 unreachable(); /* expect: 193 *//* XXX: redundant */
504 else
505 unreachable();
506
507 unreachable();
508 }
509 reachable();
510
511 if (1) {
512 if (1)
513 reachable();
514 else
515 unreachable(); /* expect: 193 */
516
517 if (0)
518 unreachable(); /* expect: 193 */
519 else
520 reachable();
521
522 reachable();
523 }
524 reachable();
525 }
526
527 void
528 test_if_maybe(void)
529 {
530 if (maybe()) {
531 if (0)
532 unreachable(); /* expect: 193 */
533 else
534 reachable();
535 reachable();
536 }
537 reachable();
538
539 if (0) {
540 if (maybe()) /* expect: 193 */
541 unreachable();
542 else
543 unreachable();
544 unreachable();
545 }
546 reachable();
547
548 if (1) {
549 if (maybe())
550 reachable();
551 else
552 reachable();
553 reachable();
554 }
555 reachable();
556 }
557
558 /*
559 * To compute the reachability graph of this little monster, lint would have
560 * to keep all statements and their relations from the whole function in
561 * memory. It doesn't do that. Therefore it does not warn about any
562 * unreachable statements in this function.
563 */
564 void
565 test_goto_numbers_alphabetically(void)
566 {
567 goto one;
568 eight:
569 goto nine;
570 five:
571 return;
572 four:
573 goto five;
574 nine:
575 goto ten;
576 one:
577 goto two;
578 seven:
579 goto eight;
580 six: /* expect: warning: label 'six' unused */
581 goto seven;
582 ten:
583 return;
584 three:
585 goto four;
586 two:
587 goto three;
588 }
589
590 void
591 test_while_goto(void)
592 {
593 while (1) {
594 goto out;
595 break; /* lint only warns with the -b option */
596 }
597 unreachable(); /* expect: 193 */
598 out:
599 reachable();
600 }
601
602 void
603 test_unreachable_label(void)
604 {
605 if (0)
606 goto unreachable; /* expect: 193 */
607 goto reachable;
608
609 /* named_label assumes that any label is reachable. */
610 unreachable:
611 unreachable();
612 reachable:
613 reachable();
614 }
615
616 /* TODO: switch */
617
618 /* TODO: system-dependent constant expression (see tn_system_dependent) */
619
620 void suppressed(void);
621
622 void
623 lint_annotation_NOTREACHED(void)
624 {
625 if (0) {
626 /* expect+1: warning: statement not reached [193] */
627 unreachable();
628 }
629
630 if (0) {
631 /* NOTREACHED */
632 suppressed();
633 }
634
635 if (0)
636 /* NOTREACHED */
637 suppressed();
638
639 if (1) {
640 reachable();
641 }
642
643 if (1) {
644 /* NOTREACHED */
645 suppressed();
646 }
647
648 /*
649 * Since the condition in the 'if' statement is constant, lint knows
650 * that the branch is unconditionally taken. The annotation comment
651 * marks that branch as not reached, which means that any following
652 * statement cannot be reached as well.
653 */
654 /* expect+1: warning: statement not reached [193] */
655 if (1)
656 /* NOTREACHED */
657 suppressed();
658 }
659
660 /*
661 * Since at least 2002 and before cgram.y 1.379 from 2022-01-16, lint did not
662 * detect a double semicolon. See cgram.y, expression_statement, T_SEMI.
663 */
664 int
665 test_null_statement(void)
666 {
667 /*
668 * The following 2 semicolons are superfluous but lint doesn't warn
669 * about them. Probably it should. A null statement as part of a
670 * block-list has no use.
671 */
672 ;;
673
674 /*
675 * A stand-alone null statement, on the other hand, has its purpose.
676 * Without it, the 'for' loop would not be complete. The NetBSD
677 * style is to use 'continue;' instead of a simple ';'.
678 */
679 for (int i = 0; i < 10; i++)
680 ;
681
682 /* expect+1: warning: statement not reached [193] */
683 return 0;;
684 }
685