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