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