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