msg_348.c revision 1.14 1 /* $NetBSD: msg_348.c,v 1.14 2025/07/11 19:03:01 rillig Exp $ */
2 # 3 "msg_348.c"
3
4 // Test for message: maximum value %d for '%s' of type '%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 *
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 equals the maximum array index. */
28 return name[color];
29 }
30
31 const char *
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 for 'blue' of type 'enum color' does not match maximum array index 1 [348] */
39 return name[color];
40 }
41
42 const char *
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 for 'blue' of type 'enum color' does not match maximum array index 3 [348] */
52 return name[color];
53 }
54
55 const char *
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 *
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 *
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 *
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
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 /* expect+1: warning: maximum value 2 for 'blue' of type 'enum color' does not match maximum array index 1 [348] */
122 if (len_2_null[color] != '\0')
123 return;
124
125 if (len_3_null[color] != '\0')
126 return;
127
128 /* expect+1: warning: maximum value 2 for 'blue' of type 'enum color' does not match maximum array index 3 [348] */
129 if (len_4_null[color] != '\0')
130 return;
131
132 /*
133 * The array has 3 elements, as expected. If lint were to inspect
134 * the content of the array, it could see that [2] is a null
135 * character. That null character may be intended though.
136 */
137 if (len_2_of_3[color] != '\0')
138 return;
139
140 if (len_3_of_3[color] != '\0')
141 return;
142
143 /* expect+1: warning: maximum value 2 for 'blue' of type 'enum color' does not match maximum array index 3 [348] */
144 if (len_4_of_4[color])
145 return;
146 }
147
148 extern const char *incomplete_color_name[];
149
150 const char *
151 color_name_incomplete_array(enum color color)
152 {
153 /* No warning since 'incomplete_color_name' is incomplete. */
154 return incomplete_color_name[color];
155 }
156
157 enum large {
158 /* expect+1: warning: constant -0x10000000000 too large for 'int' [56] */
159 min = -1LL << 40,
160 /* expect+1: warning: constant 0x10000000000 too large for 'int' [56] */
161 max = 1LL << 40,
162 zero = 0
163 };
164
165 const char *
166 large_name(enum large large)
167 {
168 static const char *name[] = {
169 "dummy",
170 };
171 /* No warning since at least 1 enum constant is outside of INT. */
172 return name[large];
173 }
174
175 enum color_with_count {
176 cc_red,
177 cc_green,
178 cc_blue,
179 cc_num_values
180 };
181
182 const char *
183 color_with_count_name(enum color_with_count color)
184 {
185 static const char *const name[] = { "red", "green", "blue" };
186 /*
187 * No warning since the word 'num' in the last enum constant
188 * MAY indicate a convenience constant for the total number of
189 * values, instead of a regular enum value.
190 */
191 return name[color];
192 }
193
194 /*
195 * If the last enum constant contains "num" in its name, it is not
196 * necessarily the count of the other enum values, it may also be a
197 * legitimate application value, therefore don't warn in this case.
198 */
199 const char *
200 color_with_num(enum color_with_count color)
201 {
202 static const char *const name[] = { "r", "g", "b", "num" };
203 /* No warning since the maximum values already match. */
204 return name[color];
205 }
206
207 enum color_with_uc_count {
208 CC_RED,
209 CC_GREEN,
210 CC_BLUE,
211 CC_NUM_VALUES
212 };
213
214 const char *
215 color_with_uc_count_name(enum color_with_uc_count color)
216 {
217 static const char *const name[] = { "red", "green", "blue" };
218 /* No warning since the maximum enum constant is a count. */
219 return name[color];
220 }
221
222 enum uppercase_max {
223 M_FIRST,
224 M_SECOND,
225 M_MAX
226 };
227
228 const char *
229 uppercase_max_name(enum uppercase_max x)
230 {
231 static const char *const name[] = { "first", "second" };
232 return name[x];
233 }
234
235 enum lowercase_max {
236 M_first,
237 M_second,
238 M_max
239 };
240
241 const char *
242 lowercase_max_name(enum lowercase_max x)
243 {
244 static const char *const name[] = { "first", "second" };
245 return name[x];
246 }
247
248 enum uppercase_n {
249 UPPERCASE_N_FIRST,
250 UPPERCASE_N_LAST,
251 N_UPPERCASE_N,
252 };
253
254 const char*
255 uppercase_n_name(enum uppercase_n x)
256 {
257 static const char *const name[] = { "first", "last" };
258 return name[x];
259 }
260
261
262 enum unit_prefix {
263 /* expect+4: previous declaration of 'MEGA' [260] */
264 /* expect+3: previous declaration of 'MEGA' [260] */
265 /* expect+2: previous declaration of 'MEGA' [260] */
266 /* expect+1: previous declaration of 'MEGA' [260] */
267 NONE = 0, KILO = 1, MEGA = 2
268 };
269
270 char
271 unit_name(enum unit_prefix prefix)
272 {
273 char name;
274
275 static const char name_short[] = "-K";
276 /* expect+1: warning: maximum value 2 for 'MEGA' of type 'enum unit_prefix' does not match maximum array index 1 [348] */
277 name = name_short[prefix];
278 /* expect+1: warning: maximum value 2 for 'MEGA' of type 'enum unit_prefix' does not match maximum array index 1 [348] */
279 name = "-K"[prefix];
280
281 static const char name_no_nul[] = { '-', 'K', 'M' };
282 name = name_no_nul[prefix];
283 name = (char[]){'-', 'K', 'M'}[prefix];
284
285 static const char name_nul[] = "-KM";
286 name = name_nul[prefix];
287 name = "-KM"[prefix];
288
289 static const char name_long[] = "-KMG";
290 /* expect+1: warning: maximum value 2 for 'MEGA' of type 'enum unit_prefix' does not match maximum array index 3 [348] */
291 name = name_long[prefix];
292 /* expect+1: warning: maximum value 2 for 'MEGA' of type 'enum unit_prefix' does not match maximum array index 3 [348] */
293 name = "-KMG"[prefix];
294
295 return name;
296 }
297