msg_130.c revision 1.15
1/*	$NetBSD: msg_130.c,v 1.15 2022/06/16 16:58:36 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	/* expect+1: warning: enum type mismatch: 'enum color' ':' 'enum daytime' [130] */
30	sink(cond ? GREEN : MORNING);
31	/* expect+1: warning: enum type mismatch: 'enum color' '!=' 'enum size' [130] */
32	sink(c != s);
33	/* expect+1: warning: enum type mismatch: 'enum color' '==' 'enum size' [130] */
34	sink(c == s);
35	sink((c & MEDIUM) != 0);	/* might be useful to warn about */
36	sink((c | MEDIUM) != 0);	/* might be useful to warn about */
37
38	c |= MEDIUM;			/* might be useful to warn about */
39	c &= MEDIUM;			/* might be useful to warn about */
40
41	/* The cast to unsigned is required by GCC at WARNS=6. */
42	c &= ~(unsigned)MEDIUM;		/* might be useful to warn about */
43}
44
45void
46switch_example(enum color c)
47{
48	switch (c) {
49	case EVENING:			/* maybe someday expect: 130 */
50	case LARGE:			/* maybe someday expect: 130 */
51	case 0:				/* maybe someday expect: 130 */
52		sink(1 == 1);
53		break;
54	default:
55		break;
56	}
57}
58
59/*
60 * Unnamed enum types can be used as a container for constants, especially
61 * since in C90 and C99, even after the declaration 'static const int x = 3',
62 * 'x' is not a constant expression.
63 */
64enum {
65	sizeof_int = sizeof(int),
66	sizeof_short = sizeof(short)
67};
68
69enum {
70	sizeof_uint = sizeof(unsigned int)
71};
72
73int
74enum_constant_from_unnamed_type(int x)
75{
76	/* using an enum constant as constant-expression */
77	switch (x) {
78	case sizeof_int:
79		return 1;
80	case sizeof_short:
81		return 2;
82	default:
83		break;
84	}
85
86	if (x == sizeof_int)
87		return 4;
88	if (x > sizeof_int)
89		return 5;
90
91	/* FIXME */
92	/* expect+1: warning: enum type mismatch: 'enum <unnamed>' '==' 'enum <unnamed>' [130] */
93	if (sizeof_int == sizeof_uint)
94		return 6;
95
96	/* expect+1: warning: statement not reached [193] */
97	return 0;
98}
99
100/*
101 * A typical legitimate use case for an anonymous enum type that should not
102 * be mixed with other types is a state machine.
103 *
104 * This example demonstrates that the type of the 'switch' expression can be
105 * an anonymous enum.
106 */
107void
108state_machine(const char *str)
109{
110	enum {
111		begin,
112		seen_letter,
113		seen_letter_digit,
114		error
115	} state = begin;
116
117	for (const char *p = str; *p != '\0'; p++) {
118		switch (state) {
119		case begin:
120			state = *p == 'A' ? seen_letter : error;
121			break;
122		case seen_letter:
123			state = *p == '1' ? seen_letter_digit : error;
124			break;
125		default:
126			state = error;
127		}
128	}
129
130	if (state == 2)			/* might be worth a warning */
131		return;
132	/* expect+1: warning: enum type mismatch: 'enum <unnamed>' '==' 'enum <unnamed>' [130] */
133	if (state == sizeof_int)
134		return;
135}
136
137/*
138 * For check_case_label_enum, a warning only makes sense if the type of the
139 * enum can actually be specified somehow, either explicitly by using a tag
140 * name or a typedef name, or implicitly by using a variable in a switch
141 * expression.
142 */
143
144typedef enum {
145	has_typedef = 1001
146} typedef_name;
147
148enum tag_name {
149	has_tag = 1002
150};
151
152enum {
153	has_variable = 1003
154} variable;
155
156enum {
157	inaccessible = 1004
158};
159
160/*
161 * This check is already done by Clang, so it may not be necessary to add it
162 * to lint as well.  Except if there are some cases that Clang didn't
163 * implement.
164 */
165void
166test_check_case_label_enum(enum color color)
167{
168	switch (color)
169	{
170	case has_typedef:
171	case has_tag:
172	case has_variable:
173	case inaccessible:
174		return;
175	}
176}
177