msg_348.c revision 1.13 1 /* $NetBSD: msg_348.c,v 1.13 2025/07/11 05:40:35 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 /* 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 for 'blue' of type '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 for 'blue' of type '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 for 'blue' of type '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 *
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: constant -0x10000000000 too large for 'int' [56] */
162 min = -1LL << 40,
163 /* expect+1: warning: constant 0x10000000000 too large for 'int' [56] */
164 max = 1LL << 40,
165 zero = 0
166 };
167
168 const char *
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 *
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 *
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 *
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 *
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 *
245 lowercase_max_name(enum lowercase_max x)
246 {
247 static const char *const name[] = { "first", "second" };
248 return name[x];
249 }
250
251 enum uppercase_n {
252 UPPERCASE_N_FIRST,
253 UPPERCASE_N_LAST,
254 N_UPPERCASE_N,
255 };
256
257 const char*
258 uppercase_n_name(enum uppercase_n x)
259 {
260 static const char *const name[] = { "first", "last" };
261 return name[x];
262 }
263
264
265 enum unit_prefix {
266 /* expect+2: previous declaration of 'MEGA' [260] */
267 /* expect+1: previous declaration of 'MEGA' [260] */
268 NONE = 0, KILO = 1, MEGA = 2
269 };
270
271 char
272 unit_name(enum unit_prefix prefix)
273 {
274 char name;
275
276 static const char name_short[] = "-K";
277 name = name_short[prefix];
278 name = "-K"[prefix];
279
280 static const char name_no_nul[] = { '-', 'K', 'M' };
281 name = name_no_nul[prefix];
282 name = (char[]){'-', 'K', 'M'}[prefix];
283
284 static const char name_nul[] = "-KM";
285 /* expect+1: warning: maximum value 2 for 'MEGA' of type 'enum unit_prefix' does not match maximum array index 3 [348] */
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 4 [348] */
291 name = name_long[prefix];
292 name = "-KMG"[prefix];
293
294 return name;
295 }
296