xref: /netbsd-src/tests/usr.bin/xlint/lint1/msg_323.c (revision b2baa50111d645353fa30b4deab0f79d93650c8c)
1 /*	$NetBSD: msg_323.c,v 1.5 2023/03/28 14:44:35 rillig Exp $	*/
2 # 3 "msg_323.c"
3 
4 // Test for message: continue in 'do ... while (0)' loop [323]
5 
6 /* lint1-extra-flags: -X 351 */
7 
8 void println(const char *);
9 
10 /*
11  * In simple cases of a do-while-0 loop, the statements 'break' and
12  * 'continue' have the same effect, and 'break' is much more common.
13  *
14  * This is also covered by Clang-Tidy.
15  */
16 void
simple_case(const char * p)17 simple_case(const char *p)
18 {
19 	do {
20 		if (p[0] == '+')
21 			break;
22 		if (p[1] == '-')
23 			continue;
24 		println("no sign");
25 	/* expect+1: error: continue in 'do ... while (0)' loop [323] */
26 	} while (0);
27 }
28 
29 /*
30  * If there is a 'switch' statement inside the do-while-0 loop, the 'break'
31  * statement is tied to the 'switch' statement instead of the loop.
32  */
33 void
nested_switch(const char * p)34 nested_switch(const char *p)
35 {
36 	do {
37 		switch (*p) {
38 		case 'a':
39 			continue;	/* leaves the 'do while 0' */
40 		case 'b':
41 			break;		/* leaves the 'switch' */
42 		}
43 		println("b");
44 	/* XXX: Is that really worth an error? */
45 	/* expect+1: error: continue in 'do ... while (0)' loop [323] */
46 	} while (0);
47 }
48 
49 /*
50  * In a nested loop, the 'continue' statement is bound to the inner loop,
51  * thus no warning.
52  */
53 void
nested_for(void)54 nested_for(void)
55 {
56 	do {
57 		for (int i = 0; i < 6; i++) {
58 			if (i < 3)
59 				continue;
60 		}
61 	} while (0);
62 }
63