1 /* $NetBSD: msg_348.c,v 1.15 2026/03/28 12:00:49 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 /* expect+1: warning: static variable 'str' set but not used [307] */ 9 static const char *str; 10 11 enum color { 12 red, 13 green, 14 /* expect+5: previous declaration of 'blue' [260] */ 15 /* expect+4: previous declaration of 'blue' [260] */ 16 /* expect+3: previous declaration of 'blue' [260] */ 17 /* expect+2: previous declaration of 'blue' [260] */ 18 /* expect+1: previous declaration of 'blue' [260] */ 19 blue 20 }; 21 22 const char * 23 color_name(enum color color) 24 { 25 static const char *name[] = { 26 "red", 27 "green", 28 "blue" 29 }; 30 /* No warning since the maximum enum value equals the maximum array index. */ 31 return name[color]; 32 } 33 34 const char * 35 color_name_too_few(enum color color) 36 { 37 static const char *name[] = { 38 "red", 39 "green" 40 }; 41 /* expect+1: warning: maximum value 2 for 'blue' of type 'enum color' does not match maximum array index 1 [348] */ 42 return name[color]; 43 } 44 45 const char * 46 color_name_too_many(enum color color) 47 { 48 static const char *name[] = { 49 "red", 50 "green", 51 "blue", 52 "black" 53 }; 54 /* expect+1: warning: maximum value 2 for 'blue' of type 'enum color' does not match maximum array index 3 [348] */ 55 return name[color]; 56 } 57 58 const char * 59 color_name_computed_index(enum color color) 60 { 61 static const char *name[] = { 62 "unused", 63 "red", 64 "green", 65 "blue" 66 }; 67 /* No warning since the array index is not a plain identifier. */ 68 return name[color + 1]; 69 } 70 71 const char * 72 color_name_cast_from_int(int c) 73 { 74 static const char *name[] = { 75 "unused", 76 "red", 77 "green", 78 "blue" 79 }; 80 /* 81 * No warning since the array index before conversion is not a plain 82 * identifier. 83 */ 84 return name[(enum color)(c + 1)]; 85 } 86 87 const char * 88 color_name_explicit_cast_to_int(enum color color) 89 { 90 static const char *name[] = { 91 "red", 92 "green", 93 }; 94 /* No warning due to the explicit cast. */ 95 return name[(int)color]; 96 } 97 98 const char * 99 color_name_computed_pointer(enum color color, const char *name) 100 { 101 /* 102 * No warning since the first operand of the selection expression 103 * is '(&name)', whose type is not an array but instead a 104 * 'pointer to pointer to const char'. 105 */ 106 return (&name)[color]; 107 } 108 109 /* 110 * If the accessed array has character type, it may contain a trailing null 111 * character. 112 */ 113 void 114 color_initial_letter(enum color color) 115 { 116 static const char len_2_null[] = "RG"; 117 static const char len_3_null[] = "RGB"; 118 static const char len_4_null[] = "RGB_"; 119 120 static const char len_2_of_3[3] = "RG"; 121 static const char len_3_of_3[3] = "RGB"; 122 static const char len_4_of_4[4] = "RGB_"; 123 124 /* expect+1: warning: maximum value 2 for 'blue' of type 'enum color' does not match maximum array index 1 [348] */ 125 if (len_2_null[color] != '\0') 126 return; 127 128 if (len_3_null[color] != '\0') 129 return; 130 131 /* expect+1: warning: maximum value 2 for 'blue' of type 'enum color' does not match maximum array index 3 [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+4: previous declaration of 'MEGA' [260] */ 267 /* expect+3: previous declaration of 'MEGA' [260] */ 268 /* expect+2: previous declaration of 'MEGA' [260] */ 269 /* expect+1: previous declaration of 'MEGA' [260] */ 270 NONE = 0, KILO = 1, MEGA = 2 271 }; 272 273 char 274 unit_name(enum unit_prefix prefix) 275 { 276 char name; 277 278 static const char name_short[] = "-K"; 279 /* expect+1: warning: maximum value 2 for 'MEGA' of type 'enum unit_prefix' does not match maximum array index 1 [348] */ 280 name = name_short[prefix]; 281 /* expect+1: warning: maximum value 2 for 'MEGA' of type 'enum unit_prefix' does not match maximum array index 1 [348] */ 282 name = "-K"[prefix]; 283 284 static const char name_no_nul[] = { '-', 'K', 'M' }; 285 name = name_no_nul[prefix]; 286 name = (char[]){'-', 'K', 'M'}[prefix]; 287 288 static const char name_nul[] = "-KM"; 289 name = name_nul[prefix]; 290 name = "-KM"[prefix]; 291 292 static const char name_long[] = "-KMG"; 293 /* expect+1: warning: maximum value 2 for 'MEGA' of type 'enum unit_prefix' does not match maximum array index 3 [348] */ 294 name = name_long[prefix]; 295 /* expect+1: warning: maximum value 2 for 'MEGA' of type 'enum unit_prefix' does not match maximum array index 3 [348] */ 296 name = "-KMG"[prefix]; 297 298 return name; 299 } 300 301 void 302 prefix_last(void) 303 { 304 enum { 305 FIRST_CONSTANT, 306 MIDDLE_CONSTANT, 307 /* expect+1: previous declaration of 'LAST_CONSTANT' [260] */ 308 LAST_CONSTANT, 309 } x = FIRST_CONSTANT; 310 311 static const char *name_ok[] = { "first", "middle" }; 312 str = name_ok[x]; 313 314 static const char *name_too_short[] = { "first" }; 315 /* expect+1: warning: maximum value 2 for 'LAST_CONSTANT' of type 'enum <unnamed>' does not match maximum array index 0 [348] */ 316 str = name_too_short[x]; 317 } 318 319 void 320 prefix_count(void) 321 { 322 enum { 323 FIRST_CONSTANT, 324 MIDDLE_CONSTANT, 325 /* expect+1: previous declaration of 'COUNT_CONSTANT' [260] */ 326 COUNT_CONSTANT, 327 } x = FIRST_CONSTANT; 328 329 static const char *name_ok[] = { "first", "middle" }; 330 str = name_ok[x]; 331 332 static const char *name_too_short[] = { "first" }; 333 /* expect+1: warning: maximum value 2 for 'COUNT_CONSTANT' of type 'enum <unnamed>' does not match maximum array index 0 [348] */ 334 str = name_too_short[x]; 335 } 336 337 void 338 suffix_count(void) 339 { 340 enum { 341 FIRST_CONSTANT, 342 MIDDLE_CONSTANT, 343 /* expect+1: previous declaration of 'CONSTANT_COUNT' [260] */ 344 CONSTANT_COUNT, 345 } x = FIRST_CONSTANT; 346 347 static const char *name_ok[] = { "first", "middle" }; 348 str = name_ok[x]; 349 350 static const char *name_too_short[] = { "first" }; 351 /* expect+1: warning: maximum value 2 for 'CONSTANT_COUNT' of type 'enum <unnamed>' does not match maximum array index 0 [348] */ 352 str = name_too_short[x]; 353 } 354 355 void 356 suffix_end(void) 357 { 358 enum { 359 FIRST_CONSTANT, 360 MIDDLE_CONSTANT, 361 /* expect+1: previous declaration of 'CONSTANT_end' [260] */ 362 CONSTANT_end, 363 } x = FIRST_CONSTANT; 364 365 static const char *name_ok[] = { "first", "middle" }; 366 str = name_ok[x]; 367 368 static const char *name_too_short[] = { "first" }; 369 /* expect+1: warning: maximum value 2 for 'CONSTANT_end' of type 'enum <unnamed>' does not match maximum array index 0 [348] */ 370 str = name_too_short[x]; 371 } 372