1/* $NetBSD: msg_348.c,v 1.10 2024/03/01 17:22:55 rillig Exp $ */ 2# 3 "msg_348.c" 3 4// Test for message: maximum value %d of '%s' does not match maximum array index %d [348] 5 6/* lint1-extra-flags: -r -X 351 */ 7 8enum 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 19const char * 20color_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 matches the array size. */ 28 return name[color]; 29} 30 31const char * 32color_name_too_few(enum color color) 33{ 34 static const char *name[] = { 35 "red", 36 "green" 37 }; 38 /* expect+1: warning: maximum value 2 of 'enum color' does not match maximum array index 1 [348] */ 39 return name[color]; 40} 41 42const char * 43color_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 of 'enum color' does not match maximum array index 3 [348] */ 52 return name[color]; 53} 54 55const char * 56color_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 68const char * 69color_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 84const char * 85color_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 95const char * 96color_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 */ 110void 111color_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 of '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 of '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 of 'enum color' does not match maximum array index 3 [348] */ 147 if (len_4_of_4[color]) 148 return; 149} 150 151extern const char *incomplete_color_name[]; 152 153const char * 154color_name_incomplete_array(enum color color) 155{ 156 /* No warning since 'incomplete_color_name' is incomplete. */ 157 return incomplete_color_name[color]; 158} 159 160enum large { 161 /* expect+1: warning: integral constant too large [56] */ 162 min = -1LL << 40, 163 /* expect+1: warning: integral constant too large [56] */ 164 max = 1LL << 40, 165 zero = 0 166}; 167 168const char * 169large_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 178enum color_with_count { 179 cc_red, 180 cc_green, 181 cc_blue, 182 cc_num_values 183}; 184 185const char * 186color_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 */ 202const char * 203color_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 210enum color_with_uc_count { 211 CC_RED, 212 CC_GREEN, 213 CC_BLUE, 214 CC_NUM_VALUES 215}; 216 217const char * 218color_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 225enum uppercase_max { 226 M_FIRST, 227 M_SECOND, 228 M_MAX 229}; 230 231const char * 232uppercase_max_name(enum uppercase_max x) 233{ 234 static const char *const name[] = { "first", "second" }; 235 return name[x]; 236} 237 238enum lowercase_max { 239 M_first, 240 M_second, 241 M_max 242}; 243 244const char * 245lowercase_max_name(enum lowercase_max x) 246{ 247 static const char *const name[] = { "first", "second" }; 248 return name[x]; 249} 250