| @@ -1,378 +1,387 @@ | | | @@ -1,378 +1,387 @@ |
1 | /* $NetBSD: d_c99_init.c,v 1.28 2021/03/30 16:09:30 rillig Exp $ */ | | 1 | /* $NetBSD: d_c99_init.c,v 1.29 2021/03/30 19:45:04 rillig Exp $ */ |
2 | # 3 "d_c99_init.c" | | 2 | # 3 "d_c99_init.c" |
3 | | | 3 | |
4 | /* | | 4 | /* |
5 | * Test C99 initializers. | | 5 | * Test C99 initializers. |
6 | * | | 6 | * |
7 | * See C99 6.7.8 "Initialization". | | 7 | * See C99 6.7.8 "Initialization". |
8 | */ | | 8 | */ |
9 | | | 9 | |
10 | | | 10 | |
11 | void use(const void *); | | 11 | void use(const void *); |
12 | | | 12 | |
13 | typedef struct any { | | 13 | typedef struct any { |
14 | const void *value; | | 14 | const void *value; |
15 | } any; | | 15 | } any; |
16 | | | 16 | |
17 | | | 17 | |
18 | // C99 6.7.8p11 says "optionally enclosed in braces". There is no limitation | | 18 | // C99 6.7.8p11 says "optionally enclosed in braces". There is no limitation |
19 | // on the number of brace pairs. | | 19 | // on the number of brace pairs. |
20 | int scalar_without_braces = 3; | | 20 | int scalar_without_braces = 3; |
21 | int scalar_with_optional_braces = { 3 }; | | 21 | int scalar_with_optional_braces = { 3 }; |
22 | int scalar_with_too_many_braces = {{ 3 }}; | | 22 | int scalar_with_too_many_braces = {{ 3 }}; |
23 | int scalar_with_too_many_initializers = { 3, 5 }; /* expect: 174 */ | | 23 | int scalar_with_too_many_initializers = { 3, 5 }; /* expect: 174 */ |
24 | | | 24 | |
25 | | | 25 | |
26 | // See init_expr, 'handing over to ASSIGN'. | | 26 | // See init_expr, 'handing over to ASSIGN'. |
27 | void | | 27 | void |
28 | struct_initialization_via_assignment(any arg) | | 28 | struct_initialization_via_assignment(any arg) |
29 | { | | 29 | { |
30 | any local = arg; | | 30 | any local = arg; |
31 | use(&local); | | 31 | use(&local); |
32 | } | | 32 | } |
33 | | | 33 | |
34 | | | 34 | |
35 | // See init_expr, initialization_init_array_using_string. | | 35 | // See init_expr, initialization_init_array_using_string. |
36 | char static_duration[] = "static duration"; | | 36 | char static_duration[] = "static duration"; |
37 | signed char static_duration_signed[] = "static duration"; | | 37 | signed char static_duration_signed[] = "static duration"; |
38 | unsigned char static_duration_unsigned[] = "static duration"; | | 38 | unsigned char static_duration_unsigned[] = "static duration"; |
39 | int static_duration_wchar[] = L"static duration"; | | 39 | int static_duration_wchar[] = L"static duration"; |
40 | | | 40 | |
41 | // See init_expr. | | 41 | // See init_expr. |
42 | void | | 42 | void |
43 | initialization_by_braced_string(void) | | 43 | initialization_by_braced_string(void) |
44 | { | | 44 | { |
45 | any local = { "hello" }; | | 45 | any local = { "hello" }; |
46 | use(&local); | | 46 | use(&local); |
47 | } | | 47 | } |
48 | | | 48 | |
49 | void | | 49 | void |
50 | initialization_by_redundantly_braced_string(void) | | 50 | initialization_by_redundantly_braced_string(void) |
51 | { | | 51 | { |
52 | any local = {{{{ "hello" }}}}; | | 52 | any local = {{{{ "hello" }}}}; |
53 | use(&local); | | 53 | use(&local); |
54 | } | | 54 | } |
55 | | | 55 | |
56 | /* | | 56 | /* |
57 | * Only scalar expressions and string literals may be enclosed by additional | | 57 | * Only scalar expressions and string literals may be enclosed by additional |
58 | * braces. Since 'arg' is a struct, this is a compile-time error. | | 58 | * braces. Since 'arg' is a struct, this is a compile-time error. |
59 | */ | | 59 | */ |
60 | void | | 60 | void |
61 | initialization_with_too_many_braces(any arg) | | 61 | initialization_with_too_many_braces(any arg) |
62 | { | | 62 | { |
63 | any local = { arg }; /* expect: 185 */ | | 63 | any local = { arg }; /* expect: 185 */ |
64 | use(&arg); | | 64 | use(&arg); |
65 | } | | 65 | } |
66 | | | 66 | |
67 | // Some of the following examples are mentioned in the introduction comment | | 67 | // Some of the following examples are mentioned in the introduction comment |
68 | // in init.c. | | 68 | // in init.c. |
69 | | | 69 | |
70 | int number = 12345; | | 70 | int number = 12345; |
71 | | | 71 | |
72 | int number_with_braces_and_comma = { | | 72 | int number_with_braces_and_comma = { |
73 | 12345, | | 73 | 12345, |
74 | }; | | 74 | }; |
75 | | | 75 | |
76 | int array_with_fixed_size[3] = { | | 76 | int array_with_fixed_size[3] = { |
77 | 111, | | 77 | 111, |
78 | 222, | | 78 | 222, |
79 | 333, | | 79 | 333, |
80 | 444, /* expect: too many array initializers */ | | 80 | 444, /* expect: too many array initializers */ |
81 | }; | | 81 | }; |
82 | | | 82 | |
83 | // See initialization_set_set_of_unknown_array. | | 83 | // See initialization_set_set_of_unknown_array. |
84 | int array_of_unknown_size[] = { | | 84 | int array_of_unknown_size[] = { |
85 | 111, | | 85 | 111, |
86 | 222, | | 86 | 222, |
87 | 333, | | 87 | 333, |
88 | }; | | 88 | }; |
89 | | | 89 | |
90 | int array_flat[2][2] = { | | 90 | int array_flat[2][2] = { |
91 | 11, | | 91 | 11, |
92 | 12, | | 92 | 12, |
93 | 21, | | 93 | 21, |
94 | 22 | | 94 | 22 |
95 | }; | | 95 | }; |
96 | | | 96 | |
97 | int array_nested[2][2] = { | | 97 | int array_nested[2][2] = { |
98 | { | | 98 | { |
99 | 11, | | 99 | 11, |
100 | 12 | | 100 | 12 |
101 | }, | | 101 | }, |
102 | { | | 102 | { |
103 | 21, | | 103 | 21, |
104 | 22 | | 104 | 22 |
105 | } | | 105 | } |
106 | }; | | 106 | }; |
107 | | | 107 | |
108 | int array_with_designators[] = { | | 108 | int array_with_designators[] = { |
109 | ['1'] = 111, | | 109 | ['1'] = 111, |
110 | ['5'] = 555, | | 110 | ['5'] = 555, |
111 | ['9'] = 999 | | 111 | ['9'] = 999 |
112 | }; | | 112 | }; |
113 | | | 113 | |
114 | int array_with_some_designators[] = { | | 114 | int array_with_some_designators[] = { |
115 | ['1'] = 111, | | 115 | ['1'] = 111, |
116 | 222, | | 116 | 222, |
117 | ['9'] = 999 | | 117 | ['9'] = 999 |
118 | }; | | 118 | }; |
119 | | | 119 | |
120 | struct point { | | 120 | struct point { |
121 | int x; | | 121 | int x; |
122 | int y; | | 122 | int y; |
123 | }; | | 123 | }; |
124 | | | 124 | |
125 | struct point point = { | | 125 | struct point point = { |
126 | 3, | | 126 | 3, |
127 | 4 | | 127 | 4 |
128 | }; | | 128 | }; |
129 | | | 129 | |
130 | struct point point_with_designators = { | | 130 | struct point point_with_designators = { |
131 | .y = 4, | | 131 | .y = 4, |
132 | .x = 3, | | 132 | .x = 3, |
133 | }; | | 133 | }; |
134 | | | 134 | |
135 | struct point point_with_mixed_designators = { | | 135 | struct point point_with_mixed_designators = { |
136 | .x = 3, | | 136 | .x = 3, |
137 | 4, | | 137 | 4, |
138 | 5, /* expect: too many struct/union initializers */ | | 138 | 5, /* expect: too many struct/union initializers */ |
139 | .x = 3, | | 139 | .x = 3, |
140 | }; | | 140 | }; |
141 | | | 141 | |
142 | int array_with_designator[] = { | | 142 | int array_with_designator[] = { |
143 | 111, | | 143 | 111, |
144 | .member = 222, /* expect: 249 */ | | 144 | .member = 222, /* expect: 249 */ |
145 | 333, | | 145 | 333, |
146 | }; | | 146 | }; |
147 | | | 147 | |
148 | /* | | 148 | /* |
149 | * C99 6.7.8p11 says that the initializer of a scalar can be "optionally | | 149 | * C99 6.7.8p11 says that the initializer of a scalar can be "optionally |
150 | * enclosed in braces". It does not explicitly set an upper limit on the | | 150 | * enclosed in braces". It does not explicitly set an upper limit on the |
151 | * number of braces. It also doesn't restrict the term "initializer" to only | | 151 | * number of braces. It also doesn't restrict the term "initializer" to only |
152 | * mean the "outermost initializer". Both GCC 10 and Clang 8 already warn | | 152 | * mean the "outermost initializer". Both GCC 10 and Clang 8 already warn |
153 | * about this, so there is no extra work for lint to do. | | 153 | * about this, so there is no extra work for lint to do. |
154 | */ | | 154 | */ |
155 | struct point scalar_with_several_braces = { | | 155 | struct point scalar_with_several_braces = { |
156 | {{{3}}}, | | 156 | {{{3}}}, |
157 | {{{{4}}}}, | | 157 | {{{{4}}}}, |
158 | }; | | 158 | }; |
159 | | | 159 | |
160 | struct rectangle { | | 160 | struct rectangle { |
161 | struct point top_left; | | 161 | struct point top_left; |
162 | struct point bottom_right; | | 162 | struct point bottom_right; |
163 | }; | | 163 | }; |
164 | | | 164 | |
165 | /* C99 6.7.8p18 */ | | 165 | /* C99 6.7.8p18 */ |
166 | struct rectangle screen = { | | 166 | struct rectangle screen = { |
167 | .bottom_right = { | | 167 | .bottom_right = { |
168 | 1920, | | 168 | 1920, |
169 | 1080, | | 169 | 1080, |
170 | } | | 170 | } |
171 | }; | | 171 | }; |
172 | | | 172 | |
173 | /* | | 173 | /* |
174 | * C99 6.7.8p22 says: At the _end_ of its initializer list, the array no | | 174 | * C99 6.7.8p22 says: At the _end_ of its initializer list, the array no |
175 | * longer has incomplete type. | | 175 | * longer has incomplete type. |
176 | */ | | 176 | */ |
177 | struct point points[] = { | | 177 | struct point points[] = { |
178 | { | | 178 | { |
179 | /* | | 179 | /* |
180 | * At this point, the size of the object 'points' is not known | | 180 | * At this point, the size of the object 'points' is not known |
181 | * yet since its type is still incomplete. Lint could warn | | 181 | * yet since its type is still incomplete. Lint could warn |
182 | * about this, but GCC and Clang already do. | | 182 | * about this, but GCC and Clang already do. |
183 | * | | 183 | * |
184 | * This test case demonstrates that in | | 184 | * This test case demonstrates that in |
185 | * extend_if_array_of_unknown_size, setcomplete is called too | | 185 | * extend_if_array_of_unknown_size, setcomplete is called too |
186 | * early. | | 186 | * early. |
187 | */ | | 187 | */ |
188 | sizeof points, | | 188 | sizeof points, |
189 | 4 | | 189 | 4 |
190 | } | | 190 | } |
191 | }; | | 191 | }; |
192 | | | 192 | |
193 | | | 193 | |
194 | struct triangle { | | 194 | struct triangle { |
195 | struct point points[3]; | | 195 | struct point points[3]; |
196 | }; | | 196 | }; |
197 | | | 197 | |
198 | struct pentagon { | | 198 | struct pentagon { |
199 | struct point points[5]; | | 199 | struct point points[5]; |
200 | }; | | 200 | }; |
201 | | | 201 | |
202 | struct geometry { | | 202 | struct geometry { |
203 | struct pentagon pentagons[6]; | | 203 | struct pentagon pentagons[6]; |
204 | struct triangle triangles[10]; | | 204 | struct triangle triangles[10]; |
205 | struct point points[3][5][2]; | | 205 | struct point points[3][5][2]; |
206 | }; | | 206 | }; |
207 | | | 207 | |
208 | /* | | 208 | /* |
209 | * Initialization of a complex struct containing nested arrays and nested | | 209 | * Initialization of a complex struct containing nested arrays and nested |
210 | * structs. | | 210 | * structs. |
211 | */ | | 211 | */ |
212 | struct geometry geometry = { | | 212 | struct geometry geometry = { |
213 | .pentagons[0].points[4].x = 1, | | 213 | .pentagons[0].points[4].x = 1, |
214 | .points[0][0][0] = { 0, 0 }, | | 214 | .points[0][0][0] = { 0, 0 }, |
215 | .points[2][4][1] = {301, 302 }, | | 215 | .points[2][4][1] = {301, 302 }, |
216 | /* expect+1: array subscript cannot be > 2: 3 */ | | 216 | /* expect+1: array subscript cannot be > 2: 3 */ |
217 | .points[3][0][0] = {3001, 3002 }, | | 217 | .points[3][0][0] = {3001, 3002 }, |
218 | /* expect+1: array subscript cannot be > 4: 5 */ | | 218 | /* expect+1: array subscript cannot be > 4: 5 */ |
219 | .points[0][5][0] = {501, 502 }, | | 219 | .points[0][5][0] = {501, 502 }, |
220 | /* expect+1: array subscript cannot be > 1: 2 */ | | 220 | /* expect+1: array subscript cannot be > 1: 2 */ |
221 | .points[0][0][2] = {21, 22 }, | | 221 | .points[0][0][2] = {21, 22 }, |
222 | }; | | 222 | }; |
223 | | | 223 | |
224 | struct ends_with_unnamed_bit_field { | | 224 | struct ends_with_unnamed_bit_field { |
225 | int member; | | 225 | int member; |
226 | int : 0; | | 226 | int : 0; |
227 | } ends_with_unnamed_bit_field = { | | 227 | } ends_with_unnamed_bit_field = { |
228 | 12345, | | 228 | 12345, |
229 | /* expect+1: too many struct/union initializers */ | | 229 | /* expect+1: too many struct/union initializers */ |
230 | 23456, | | 230 | 23456, |
231 | }; | | 231 | }; |
232 | | | 232 | |
233 | char prefixed_message[] = { | | 233 | char prefixed_message[] = { |
234 | 'E', ':', ' ', | | 234 | 'E', ':', ' ', |
235 | /* expect+1: illegal combination of integer (char) and pointer */ | | 235 | /* expect+1: illegal combination of integer (char) and pointer */ |
236 | "message\n", | | 236 | "message\n", |
237 | }; | | 237 | }; |
238 | | | 238 | |
239 | char message_with_suffix[] = { | | 239 | char message_with_suffix[] = { |
240 | "message", /* expect: illegal combination */ | | 240 | "message", /* expect: illegal combination */ |
241 | /* */ | | 241 | /* */ |
242 | '\n', | | 242 | '\n', |
243 | }; | | 243 | }; |
244 | | | 244 | |
245 | struct ten { | | 245 | struct ten { |
246 | int i0; | | 246 | int i0; |
247 | int i1; | | 247 | int i1; |
248 | int i2; | | 248 | int i2; |
249 | int i3; | | 249 | int i3; |
250 | int i4; | | 250 | int i4; |
251 | int i5; | | 251 | int i5; |
252 | int i6; | | 252 | int i6; |
253 | int i7; | | 253 | int i7; |
254 | int i8; | | 254 | int i8; |
255 | int i9; | | 255 | int i9; |
256 | }; | | 256 | }; |
257 | | | 257 | |
258 | struct ten ten = { | | 258 | struct ten ten = { |
259 | .i3 = 3, | | 259 | .i3 = 3, |
260 | 4, | | 260 | 4, |
261 | 5, | | 261 | 5, |
262 | 6, | | 262 | 6, |
263 | }; | | 263 | }; |
264 | | | 264 | |
265 | int c99_6_7_8_p26_example3[4][3] = { | | 265 | int c99_6_7_8_p26_example3[4][3] = { |
266 | { 1, 3, 5 }, | | 266 | { 1, 3, 5 }, |
267 | { 2, 4, 6 }, | | 267 | { 2, 4, 6 }, |
268 | { 3, 5, 7 }, | | 268 | { 3, 5, 7 }, |
269 | }; | | 269 | }; |
270 | | | 270 | |
271 | int c99_6_7_8_p27_example4[4][3] = { | | 271 | int c99_6_7_8_p27_example4[4][3] = { |
272 | { 1 }, { 2 }, { 3 }, { 4 } | | 272 | { 1 }, { 2 }, { 3 }, { 4 } |
273 | }; | | 273 | }; |
274 | | | 274 | |
275 | struct { | | 275 | struct { |
276 | int a[3], b; | | 276 | int a[3], b; |
277 | } c99_6_7_8_p28_example5[] = { | | 277 | } c99_6_7_8_p28_example5[] = { |
278 | { 1 }, | | 278 | { 1 }, |
279 | 2, /* XXX *//* expect: cannot initialize */ | | 279 | 2, /* XXX *//* expect: cannot initialize */ |
280 | }; | | 280 | }; |
281 | | | 281 | |
282 | short c99_6_7_8_p29_example6a[4][3][2] = { | | 282 | short c99_6_7_8_p29_example6a[4][3][2] = { |
283 | { 1 }, | | 283 | { 1 }, |
284 | { 2, 3 }, | | 284 | { 2, 3 }, |
285 | { 4, 5, 6 }, | | 285 | { 4, 5, 6 }, |
286 | }; | | 286 | }; |
287 | | | 287 | |
288 | short c99_6_7_8_p29_example6b[4][3][2] = { | | 288 | short c99_6_7_8_p29_example6b[4][3][2] = { |
289 | 1, 0, 0, 0, 0, 0, | | 289 | 1, 0, 0, 0, 0, 0, |
290 | 2, 3, 0, 0, 0, 0, | | 290 | 2, 3, 0, 0, 0, 0, |
291 | 4, 5, 6, 0, 0, 0, | | 291 | 4, 5, 6, 0, 0, 0, |
292 | }; | | 292 | }; |
293 | | | 293 | |
294 | short c99_6_7_8_p29_example6c[4][3][2] = { | | 294 | short c99_6_7_8_p29_example6c[4][3][2] = { |
295 | { | | 295 | { |
296 | { 1 }, | | 296 | { 1 }, |
297 | }, | | 297 | }, |
298 | { | | 298 | { |
299 | { 2, 3 }, | | 299 | { 2, 3 }, |
300 | }, | | 300 | }, |
301 | { | | 301 | { |
302 | { 4, 5 }, | | 302 | { 4, 5 }, |
303 | { 6 }, | | 303 | { 6 }, |
304 | } | | 304 | } |
305 | }; | | 305 | }; |
306 | | | 306 | |
307 | /* | | 307 | /* |
308 | * During initialization of an object of type array of unknown size, the type | | 308 | * During initialization of an object of type array of unknown size, the type |
309 | * information on the symbol is updated in-place. Ensure that this happens on | | 309 | * information on the symbol is updated in-place. Ensure that this happens on |
310 | * a copy of the type. | | 310 | * a copy of the type. |
311 | */ | | 311 | */ |
312 | void | | 312 | void |
313 | ensure_array_type_is_not_modified_during_initialization(void) | | 313 | ensure_array_type_is_not_modified_during_initialization(void) |
314 | { | | 314 | { |
315 | typedef int array_of_unknown_size[]; | | 315 | typedef int array_of_unknown_size[]; |
316 | | | 316 | |
317 | array_of_unknown_size a1 = { 1, 2, 3}; | | 317 | array_of_unknown_size a1 = { 1, 2, 3}; |
318 | | | 318 | |
319 | switch (4) { | | 319 | switch (4) { |
320 | case sizeof(array_of_unknown_size): | | 320 | case sizeof(array_of_unknown_size): |
321 | case 0: /* expect: duplicate case in switch: 0 */ | | 321 | case 0: /* expect: duplicate case in switch: 0 */ |
322 | case 3: | | 322 | case 3: |
323 | case 4: | | 323 | case 4: |
324 | case 12: | | 324 | case 12: |
325 | break; | | 325 | break; |
326 | } | | 326 | } |
327 | } | | 327 | } |
328 | | | 328 | |
329 | struct point unknown_member_name_beginning = { | | 329 | struct point unknown_member_name_beginning = { |
330 | .r = 5, /* expect: does not have member 'r' */ | | 330 | .r = 5, /* expect: does not have member 'r' */ |
331 | .x = 4, | | 331 | .x = 4, |
332 | .y = 3, | | 332 | .y = 3, |
333 | }; | | 333 | }; |
334 | | | 334 | |
335 | struct point unknown_member_name_middle = { | | 335 | struct point unknown_member_name_middle = { |
336 | .x = 4, | | 336 | .x = 4, |
337 | .r = 5, /* expect: does not have member 'r' */ | | 337 | .r = 5, /* expect: does not have member 'r' */ |
338 | .y = 3, | | 338 | .y = 3, |
339 | }; | | 339 | }; |
340 | | | 340 | |
341 | struct point unknown_member_name_end = { | | 341 | struct point unknown_member_name_end = { |
342 | .x = 4, | | 342 | .x = 4, |
343 | .y = 3, | | 343 | .y = 3, |
344 | .r = 5, /* expect: does not have member 'r' */ | | 344 | .r = 5, /* expect: does not have member 'r' */ |
345 | }; | | 345 | }; |
346 | | | 346 | |
347 | union value { | | 347 | union value { |
348 | int int_value; | | 348 | int int_value; |
349 | void *pointer_value; | | 349 | void *pointer_value; |
350 | }; | | 350 | }; |
351 | | | 351 | |
352 | union value unknown_union_member_name_first = { | | 352 | union value unknown_union_member_name_first = { |
353 | .unknown_value = 4, /* expect: does not have member */ | | 353 | .unknown_value = 4, /* expect: does not have member */ |
354 | .int_value = 3, | | 354 | .int_value = 3, |
355 | }; | | 355 | }; |
356 | | | 356 | |
357 | union value unknown_union_member_name_second = { | | 357 | union value unknown_union_member_name_second = { |
358 | .int_value = 3, | | 358 | .int_value = 3, |
359 | .unknown_value = 4, /* expect: does not have member */ | | 359 | .unknown_value = 4, /* expect: does not have member */ |
360 | }; | | 360 | }; |
361 | | | 361 | |
362 | struct point designators_with_subscript = { | | 362 | struct point designators_with_subscript = { |
363 | [0] = 3, /* expect: only for arrays */ | | 363 | [0] = 3, /* expect: only for arrays */ |
364 | .member[0][0].member = 4, /* expect: does not have member 'member' */ | | 364 | .member[0][0].member = 4, /* expect: does not have member 'member' */ |
365 | .x.y.z = 5, /* intentionally not caught, see designator_look_up */ | | 365 | .x.y.z = 5, /* intentionally not caught, see designator_look_up */ |
366 | }; | | 366 | }; |
367 | | | 367 | |
368 | struct { | | 368 | struct { |
369 | int : 16; | | 369 | int : 16; |
370 | } struct_with_only_unnamed_members = { /* expect: has no named members */ | | 370 | } struct_with_only_unnamed_members = { /* expect: has no named members */ |
371 | 123, /* expect: too many struct/union initializers */ | | 371 | 123, /* expect: too many struct/union initializers */ |
372 | }; | | 372 | }; |
373 | | | 373 | |
374 | union { | | 374 | union { |
375 | int : 16; | | 375 | int : 16; |
376 | } union_with_only_unnamed_members = { /* expect: has no named members */ | | 376 | } union_with_only_unnamed_members = { /* expect: has no named members */ |
377 | 123, /* expect: too many struct/union initializers */ | | 377 | 123, /* expect: too many struct/union initializers */ |
378 | }; | | 378 | }; |
| | | 379 | |
| | | 380 | int designator_for_scalar = { |
| | | 381 | .value = 3, /* expect: scalar type cannot use designator */ |
| | | 382 | }; |
| | | 383 | |
| | | 384 | struct point designator_for_scalar_in_struct = { |
| | | 385 | { .x = 3 }, /* expect: scalar type cannot use designator */ |
| | | 386 | { [1] = 4 }, /* expect: scalar type cannot use designator */ |
| | | 387 | }; |