Home | History | Annotate | Line # | Download | only in lint1
      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