xref: /netbsd/tests/usr.bin/xlint/lint1/msg_348.c (revision ea649623)
1 /*	$NetBSD: msg_348.c,v 1.9 2023/03/28 14:44:35 rillig Exp $	*/
2 # 3 "msg_348.c"
3 
4 // Test for message 348: maximum value %d of '%s' does not match maximum array index %d [348]
5 
6 /* lint1-extra-flags: -r -X 351 */
7 
8 enum color {
9 	red,
10 	green,
11 	/* expect+5: previous declaration of 'blue' [260] */
12 	/* expect+4: previous declaration of 'blue' [260] */
13 	/* expect+3: previous declaration of 'blue' [260] */
14 	/* expect+2: previous declaration of 'blue' [260] */
15 	/* expect+1: previous declaration of 'blue' [260] */
16 	blue
17 };
18 
19 const char *
color_name(enum color color)20 color_name(enum color color)
21 {
22 	static const char *name[] = {
23 	    "red",
24 	    "green",
25 	    "blue"
26 	};
27 	/* No warning since the maximum enum value matches the array size. */
28 	return name[color];
29 }
30 
31 const char *
color_name_too_few(enum color color)32 color_name_too_few(enum color color)
33 {
34 	static const char *name[] = {
35 	    "red",
36 	    "green"
37 	};
38 	/* expect+1: warning: maximum value 2 of 'enum color' does not match maximum array index 1 [348] */
39 	return name[color];
40 }
41 
42 const char *
color_name_too_many(enum color color)43 color_name_too_many(enum color color)
44 {
45 	static const char *name[] = {
46 	    "red",
47 	    "green",
48 	    "blue",
49 	    "black"
50 	};
51 	/* expect+1: warning: maximum value 2 of 'enum color' does not match maximum array index 3 [348] */
52 	return name[color];
53 }
54 
55 const char *
color_name_computed_index(enum color color)56 color_name_computed_index(enum color color)
57 {
58 	static const char *name[] = {
59 	    "unused",
60 	    "red",
61 	    "green",
62 	    "blue"
63 	};
64 	/* No warning since the array index is not a plain identifier. */
65 	return name[color + 1];
66 }
67 
68 const char *
color_name_cast_from_int(int c)69 color_name_cast_from_int(int c)
70 {
71 	static const char *name[] = {
72 	    "unused",
73 	    "red",
74 	    "green",
75 	    "blue"
76 	};
77 	/*
78 	 * No warning since the array index before conversion is not a plain
79 	 * identifier.
80 	 */
81 	return name[(enum color)(c + 1)];
82 }
83 
84 const char *
color_name_explicit_cast_to_int(enum color color)85 color_name_explicit_cast_to_int(enum color color)
86 {
87 	static const char *name[] = {
88 	    "red",
89 	    "green",
90 	};
91 	/* No warning due to the explicit cast. */
92 	return name[(int)color];
93 }
94 
95 const char *
color_name_computed_pointer(enum color color,const char * name)96 color_name_computed_pointer(enum color color, const char *name)
97 {
98 	/*
99 	 * No warning since the first operand of the selection expression
100 	 * is '(&name)', whose type is not an array but instead a
101 	 * 'pointer to pointer to const char'.
102 	 */
103 	return (&name)[color];
104 }
105 
106 /*
107  * If the accessed array has character type, it may contain a trailing null
108  * character.
109  */
110 void
color_initial_letter(enum color color)111 color_initial_letter(enum color color)
112 {
113 	static const char len_2_null[] = "RG";
114 	static const char len_3_null[] = "RGB";
115 	static const char len_4_null[] = "RGB_";
116 
117 	static const char len_2_of_3[3] = "RG";
118 	static const char len_3_of_3[3] = "RGB";
119 	static const char len_4_of_4[4] = "RGB_";
120 
121 	/* TODO: array is too short */
122 	if (len_2_null[color] != '\0')
123 		return;
124 
125 	/* FIXME: lint should not warn since the maximum usable array index is 2 */
126 	/* expect+1: warning: maximum value 2 of 'enum color' does not match maximum array index 3 [348] */
127 	if (len_3_null[color] != '\0')
128 		return;
129 
130 	/* FIXME: lint should not warn since the maximum usable array index is 3, not 4 */
131 	/* expect+1: warning: maximum value 2 of 'enum color' does not match maximum array index 4 [348] */
132 	if (len_4_null[color] != '\0')
133 		return;
134 
135 	/*
136 	 * The array has 3 elements, as expected.  If lint were to inspect
137 	 * the content of the array, it could see that [2] is a null
138 	 * character.  That null character may be intended though.
139 	 */
140 	if (len_2_of_3[color] != '\0')
141 		return;
142 
143 	if (len_3_of_3[color] != '\0')
144 		return;
145 
146 	/* expect+1: warning: maximum value 2 of 'enum color' does not match maximum array index 3 [348] */
147 	if (len_4_of_4[color])
148 		return;
149 }
150 
151 extern const char *incomplete_color_name[];
152 
153 const char *
color_name_incomplete_array(enum color color)154 color_name_incomplete_array(enum color color)
155 {
156 	/* No warning since 'incomplete_color_name' is incomplete. */
157 	return incomplete_color_name[color];
158 }
159 
160 enum large {
161 	/* expect+1: warning: integral constant too large [56] */
162 	min = -1LL << 40,
163 	/* expect+1: warning: integral constant too large [56] */
164 	max = 1LL << 40,
165 	zero = 0
166 };
167 
168 const char *
large_name(enum large large)169 large_name(enum large large)
170 {
171 	static const char *name[] = {
172 	    "dummy",
173 	};
174 	/* No warning since at least 1 enum constant is outside of INT. */
175 	return name[large];
176 }
177 
178 enum color_with_count {
179 	cc_red,
180 	cc_green,
181 	cc_blue,
182 	cc_num_values
183 };
184 
185 const char *
color_with_count_name(enum color_with_count color)186 color_with_count_name(enum color_with_count color)
187 {
188 	static const char *const name[] = { "red", "green", "blue" };
189 	/*
190 	 * No warning since the word 'num' in the last enum constant
191 	 * MAY indicate a convenience constant for the total number of
192 	 * values, instead of a regular enum value.
193 	 */
194 	return name[color];
195 }
196 
197 /*
198  * If the last enum constant contains "num" in its name, it is not
199  * necessarily the count of the other enum values, it may also be a
200  * legitimate application value, therefore don't warn in this case.
201  */
202 const char *
color_with_num(enum color_with_count color)203 color_with_num(enum color_with_count color)
204 {
205 	static const char *const name[] = { "r", "g", "b", "num" };
206 	/* No warning since the maximum values already match. */
207 	return name[color];
208 }
209 
210 enum color_with_uc_count {
211 	CC_RED,
212 	CC_GREEN,
213 	CC_BLUE,
214 	CC_NUM_VALUES
215 };
216 
217 const char *
color_with_uc_count_name(enum color_with_uc_count color)218 color_with_uc_count_name(enum color_with_uc_count color)
219 {
220 	static const char *const name[] = { "red", "green", "blue" };
221 	/* No warning since the maximum enum constant is a count. */
222 	return name[color];
223 }
224 
225 enum uppercase_max {
226 	M_FIRST,
227 	M_SECOND,
228 	M_MAX
229 };
230 
231 const char *
uppercase_max_name(enum uppercase_max x)232 uppercase_max_name(enum uppercase_max x)
233 {
234 	static const char *const name[] = { "first", "second" };
235 	return name[x];
236 }
237 
238 enum lowercase_max {
239 	M_first,
240 	M_second,
241 	M_max
242 };
243 
244 const char *
lowercase_max_name(enum lowercase_max x)245 lowercase_max_name(enum lowercase_max x)
246 {
247 	static const char *const name[] = { "first", "second" };
248 	return name[x];
249 }
250