msg_130.c revision 1.12
1/*	$NetBSD: msg_130.c,v 1.12 2021/03/21 15:24:56 rillig Exp $	*/
2# 3 "msg_130.c"
3
4// Test for message: enum type mismatch: '%s' '%s' '%s' [130]
5
6/* See also msg_241.c, which covers unusual operators on enums. */
7
8enum color {
9	RED	= 1 << 0,
10	GREEN	= 1 << 1,
11	BLUE	= 1 << 2
12};
13
14enum size {
15	SMALL,
16	MEDIUM,
17	LARGE
18};
19
20enum daytime {
21	NIGHT, MORNING, NOON, EVENING
22};
23
24void sink(_Bool);
25
26void
27example(_Bool cond, enum color c, enum size s)
28{
29	sink(cond ? GREEN : MORNING);	/* expect: 130 */
30
31	sink(c != s);			/* expect: 130 */
32	sink(c == s);			/* expect: 130 */
33	sink((c & MEDIUM) != 0);	/* might be useful to warn about */
34	sink((c | MEDIUM) != 0);	/* might be useful to warn about */
35
36	c |= MEDIUM;			/* might be useful to warn about */
37	c &= MEDIUM;			/* might be useful to warn about */
38
39	/* The cast to unsigned is required by GCC at WARNS=6. */
40	c &= ~(unsigned)MEDIUM;		/* might be useful to warn about */
41}
42
43void
44switch_example(enum color c)
45{
46	switch (c) {
47	case EVENING:			/* maybe someday expect: 130 */
48	case LARGE:			/* maybe someday expect: 130 */
49	case 0:				/* maybe someday expect: 130 */
50		sink(1 == 1);
51		break;
52	default:
53		break;
54	}
55}
56
57/*
58 * Unnamed enum types can be used as a container for constants, especially
59 * since in C90 and C99, even after the declaration 'static const int x = 3',
60 * 'x' is not a constant expression.
61 */
62enum {
63	sizeof_int = sizeof(int),
64	sizeof_long = sizeof(long)
65};
66
67enum {
68	sizeof_uint = sizeof(unsigned int)
69};
70
71int
72enum_constant_from_unnamed_type(int x)
73{
74	/* using an enum constant as constant-expression */
75	switch (x) {
76	case sizeof_int:
77		return 1;
78	case sizeof_long:
79		return 2;
80	default:
81		break;
82	}
83
84	if (x == sizeof_int)
85		return 4;
86	if (x > sizeof_int)
87		return 5;
88
89	if (sizeof_int == sizeof_uint)	/* expect: 130 *//* FIXME */
90		return 6;
91
92	return 0;		/* expect: statement not reached */
93}
94
95/*
96 * A typical legitimate use case for an anonymous enum type that should not
97 * be mixed with other types is a state machine.
98 *
99 * This example demonstrates that the type of the 'switch' expression can be
100 * an anonymous enum.
101 */
102void
103state_machine(const char *str)
104{
105	enum {
106		begin,
107		seen_letter,
108		seen_letter_digit,
109		error
110	} state = begin;
111
112	for (const char *p = str; *p != '\0'; p++) {
113		switch (state) {
114		case begin:
115			state = *p == 'A' ? seen_letter : error;
116			break;
117		case seen_letter:
118			state = *p == '1' ? seen_letter_digit : error;
119			break;
120		default:
121			state = error;
122		}
123	}
124
125	if (state == 2)			/* might be worth a warning */
126		return;
127	if (state == sizeof_int)	/* expect: 130 */
128		return;
129}
130