init_c99.c revision 1.1 1 /* $NetBSD: init_c99.c,v 1.1 2024/06/08 13:50:47 rillig Exp $ */
2 # 3 "init_c99.c"
3
4 // Tests for initialization in C99 or later, mainly for designators.
5 //
6 // See C99 6.7.8 "Initialization".
7
8 /* lint1-flags: -Sw -X 351 */
9
10 void use(const void *);
11
12 typedef struct any {
13 const void *value;
14 } any;
15
16
17 // C99 6.7.8p11 says "optionally enclosed in braces". Whether this wording
18 // means "a single pair of braces" or "as many pairs of braces as you want"
19 // is left for interpretation to the reader.
20 int scalar_without_braces = 3;
21 int scalar_with_optional_braces = { 3 };
22 int scalar_with_too_many_braces = {{ 3 }};
23 /* expect+1: error: too many initializers for 'int' [174] */
24 int scalar_with_too_many_initializers = { 3, 5 };
25
26
27 // See initialization_expr, 'handing over to INIT'.
28 void
29 struct_initialization_via_assignment(any arg)
30 {
31 any local = arg;
32 use(&local);
33 }
34
35
36 // See initialization_expr, initialization_init_array_from_string.
37 char static_duration[] = "static duration";
38 signed char static_duration_signed[] = "static duration";
39 unsigned char static_duration_unsigned[] = "static duration";
40 int static_duration_wchar[] = L"static duration";
41
42 // See init_expr.
43 void
44 initialization_by_braced_string(void)
45 {
46 any local = { "hello" };
47 use(&local);
48 }
49
50 void
51 initialization_by_redundantly_braced_string(void)
52 {
53 any local = {{{{ "hello" }}}};
54 use(&local);
55 }
56
57 /*
58 * Only scalar expressions and string literals may be enclosed by additional
59 * braces. Since 'arg' is a struct, this is a compile-time error.
60 */
61 void
62 initialization_with_too_many_braces(any arg)
63 {
64 /* expect+1: error: cannot initialize 'pointer to const void' from 'struct any' [185] */
65 any local = { arg };
66 use(&arg);
67 }
68
69 // Some of the following examples are mentioned in the introduction comment
70 // in init.c.
71
72 int number = 12345;
73
74 int number_with_braces_and_comma = {
75 12345,
76 };
77
78 int array_with_fixed_size[3] = {
79 111,
80 222,
81 333,
82 /* expect+1: error: too many array initializers, expected 3 [173] */
83 444,
84 };
85
86 // See update_type_of_array_of_unknown_size.
87 int array_of_unknown_size[] = {
88 111,
89 222,
90 333,
91 };
92
93 int array_flat[2][2] = {
94 11,
95 12,
96 21,
97 22
98 };
99
100 int array_nested[2][2] = {
101 {
102 11,
103 12
104 },
105 {
106 21,
107 22
108 }
109 };
110
111 int array_with_designators[] = {
112 ['1'] = 111,
113 ['5'] = 555,
114 ['9'] = 999
115 };
116
117 int array_with_some_designators[] = {
118 ['1'] = 111,
119 222,
120 ['9'] = 999
121 };
122
123 struct point {
124 int x;
125 int y;
126 };
127
128 struct point point = {
129 3,
130 4
131 };
132
133 struct point point_with_designators = {
134 .y = 4,
135 .x = 3,
136 };
137
138 struct point point_with_mixed_designators = {
139 .x = 3,
140 4,
141 /* expect+1: error: too many struct/union initializers [172] */
142 5,
143 .x = 3,
144 };
145
146 /*
147 * Before cgram.y 1.230 from 2021-06-20, the grammar allowed either of the
148 * operators '.' or '->' to be used for the designators and had extra code
149 * to ensure that only '.' was actually used.
150 */
151 struct point origin = {
152 .x = 0,
153 /* expect+1: error: syntax error '->' [249] */
154 ->y = 0,
155 };
156
157 /* Ensure that the parser can recover from the parse error. */
158 struct point pythagoras = { 3, 4 };
159
160 int array_with_designator[] = {
161 111,
162 /* expect+1: error: syntax error 'designator '.member' is only for struct/union' [249] */
163 .member = 222,
164 333,
165 };
166
167 /*
168 * C99 6.7.8p11 says that the initializer of a scalar can be "optionally
169 * enclosed in braces". It does not explicitly set an upper limit on the
170 * number of braces. It also doesn't restrict the term "initializer" to only
171 * mean the "outermost initializer". 6.7.8p13 defines that a brace for a
172 * structure or union always means to descend into the type. Both GCC 10 and
173 * Clang 8 already warn about these extra braces, nevertheless there is
174 * real-life code (the Postfix MTA) that exploits this corner case of the
175 * standard.
176 */
177 struct point scalar_with_several_braces = {
178 {{{3}}},
179 {{{{4}}}},
180 };
181
182 struct rectangle {
183 struct point top_left;
184 struct point bottom_right;
185 };
186
187 /* C99 6.7.8p18 */
188 struct rectangle screen = {
189 .bottom_right = {
190 1920,
191 1080,
192 }
193 };
194
195 /*
196 * C99 6.7.8p22 says: At the _end_ of its initializer list, the array no
197 * longer has incomplete type.
198 */
199 struct point points[] = {
200 {
201 /*
202 * At this point, the size of the object 'points' is not known
203 * yet since its type is still incomplete. Lint could warn
204 * about this, but GCC and Clang already do.
205 *
206 * Before init.c 1.179 from 2021.03.30, the type information
207 * of 'points' was set too early, resulting in a negative
208 * array size below.
209 */
210 sizeof(int[-(int)sizeof(points)]),
211 4
212 }
213 };
214
215
216 struct triangle {
217 struct point points[3];
218 };
219
220 struct pentagon {
221 struct point points[5];
222 };
223
224 struct geometry {
225 struct pentagon pentagons[6];
226 struct triangle triangles[10];
227 struct point points[3][5][2];
228 };
229
230 /*
231 * Initialization of a complex struct containing nested arrays and nested
232 * structs.
233 */
234 struct geometry geometry = {
235 .pentagons[0].points[4].x = 1,
236 .points[0][0][0] = { 0, 0 },
237 .points[2][4][1] = {301, 302 },
238 /* expect+1: error: array subscript 3 cannot be > 2 [168] */
239 .points[3][0][0] = {3001, 3002 },
240 /* expect+1: error: array subscript 5 cannot be > 4 [168] */
241 .points[0][5][0] = {501, 502 },
242 /* expect+1: error: array subscript 2 cannot be > 1 [168] */
243 .points[0][0][2] = {21, 22 },
244 };
245
246 struct ends_with_unnamed_bit_field {
247 int member;
248 int:0;
249 } ends_with_unnamed_bit_field = {
250 12345,
251 /* expect+1: error: too many struct/union initializers [172] */
252 23456,
253 };
254
255 char prefixed_message[] = {
256 'E', ':', ' ',
257 /* expect+1: warning: illegal combination of integer 'char' and pointer 'pointer to char' [183] */
258 "message\n",
259 };
260
261 char message_with_suffix[] = {
262 "message",
263 /* The excess character is not detected by lint but by compilers. */
264 '\n',
265 };
266
267 struct ten {
268 int i0;
269 int i1;
270 int i2;
271 int i3;
272 int i4;
273 int i5;
274 int i6;
275 int i7;
276 int i8;
277 int i9;
278 };
279
280 struct ten ten = {
281 .i3 = 3,
282 4,
283 5,
284 6,
285 };
286
287
288 /*
289 * ISO C99 6.7.8 provides a large list of examples for initialization,
290 * covering all tricky edge cases.
291 */
292
293 int c99_6_7_8_p24_example1_i = 3.5;
294 double _Complex c99_6_7_8_p24_example1_c = 5 + 3 * 1.0fi;
295
296 int c99_6_7_8_p25_example2[] = { 1, 3, 5 };
297
298 int c99_6_7_8_p26_example3a[4][3] = {
299 { 1, 3, 5 },
300 { 2, 4, 6 },
301 { 3, 5, 7 },
302 };
303
304 int c99_6_7_8_p26_example3b[4][3] = {
305 1, 3, 5, 2, 4, 6, 3, 5, 7
306 };
307
308 int c99_6_7_8_p27_example4[4][3] = {
309 { 1 }, { 2 }, { 3 }, { 4 }
310 };
311
312 struct {
313 int a[3], b;
314 } c99_6_7_8_p28_example5[] = {
315 { 1 },
316 2,
317 };
318
319 short c99_6_7_8_p29_example6a[4][3][2] = {
320 { 1 },
321 { 2, 3 },
322 { 4, 5, 6 },
323 };
324
325 short c99_6_7_8_p29_example6b[4][3][2] = {
326 1, 0, 0, 0, 0, 0,
327 2, 3, 0, 0, 0, 0,
328 4, 5, 6, 0, 0, 0,
329 };
330
331 short c99_6_7_8_p29_example6c[4][3][2] = {
332 {
333 { 1 },
334 },
335 {
336 { 2, 3 },
337 },
338 {
339 { 4, 5 },
340 { 6 },
341 }
342 };
343
344 void
345 c99_6_7_8_p31_example7(void)
346 {
347 typedef int A[];
348
349 A a = { 1, 2 }, b = { 3, 4, 5 };
350
351 /* expect+1: error: negative array dimension (-8) [20] */
352 typedef int reveal_sizeof_a[-(int)(sizeof(a))];
353 /* expect+1: error: negative array dimension (-12) [20] */
354 typedef int reveal_sizeof_b[-(int)(sizeof(b))];
355 }
356
357 char c99_6_7_8_p32_example8_s1[] = "abc",
358 c99_6_7_8_p32_example8_t1[3] = "abc";
359 char c99_6_7_8_p32_example8_s2[] = { 'a', 'b', 'c', '\0' },
360 c99_6_7_8_p32_example8_t2[3] = { 'a', 'b', 'c' };
361 char *c99_6_7_8_p32_example8_p = "abc";
362
363 enum { member_one, member_two };
364 const char *c99_6_7_8_p33_example9[] = {
365 [member_two] = "member two",
366 [member_one] = "member one",
367 };
368
369 struct {
370 int quot, rem;
371 } c99_6_7_8_p34_example10 = { .quot = 2, .rem = -1 };
372
373 struct { int a[3], b; } c99_6_7_8_p35_example11[] =
374 { [0].a = {1}, [1].a[0] = 2 };
375
376 int c99_6_7_8_p36_example12a[16] = {
377 1, 3, 5, 7, 9, [16-5] = 8, 6, 4, 2, 0
378 };
379
380 int c99_6_7_8_p36_example12b[8] = {
381 1, 3, 5, 7, 9, [8-5] = 8, 6, 4, 2, 0
382 };
383
384 union {
385 int first_member;
386 void *second_member;
387 unsigned char any_member;
388 } c99_6_7_8_p38_example13 = { .any_member = 42 };
389
390
391 /*
392 * During initialization of an object of type array of unknown size, the type
393 * information on the symbol is updated in-place. Ensure that this happens on
394 * a copy of the type.
395 *
396 * C99 6.7.8p31 example 7
397 */
398 void
399 ensure_array_type_is_not_modified_during_initialization(void)
400 {
401 typedef int array_of_unknown_size[];
402
403 array_of_unknown_size a1 = { 1, 2, 3};
404
405 switch (4) {
406 case sizeof(array_of_unknown_size):
407 /* expect+1: error: duplicate case '0' in switch [199] */
408 case 0:
409 case 3:
410 case 4:
411 case 12:
412 break;
413 }
414
415 /* expect+1: error: negative array dimension (-12) [20] */
416 typedef int reveal_sizeof_a1[-(int)(sizeof(a1))];
417 }
418
419 struct point unknown_member_name_beginning = {
420 /* expect+1: error: type 'struct point' does not have member 'r' [101] */
421 .r = 5,
422 .x = 4,
423 .y = 3,
424 };
425
426 struct point unknown_member_name_middle = {
427 .x = 4,
428 /* expect+1: error: type 'struct point' does not have member 'r' [101] */
429 .r = 5,
430 .y = 3,
431 };
432
433 struct point unknown_member_name_end = {
434 .x = 4,
435 .y = 3,
436 /* expect+1: error: type 'struct point' does not have member 'r' [101] */
437 .r = 5,
438 };
439
440 union value {
441 int int_value;
442 void *pointer_value;
443 };
444
445 union value unknown_union_member_name_first = {
446 /* expect+1: error: type 'union value' does not have member 'unknown_value' [101] */
447 .unknown_value = 4,
448 .int_value = 3,
449 };
450
451 union value unknown_union_member_name_second = {
452 .int_value = 3,
453 /* expect+1: error: type 'union value' does not have member 'unknown_value' [101] */
454 .unknown_value = 4,
455 };
456
457 struct point subscript_designator_on_struct = {
458 /* expect+1: error: syntax error 'designator '[...]' is only for arrays' [249] */
459 [0] = 3,
460 };
461
462 struct point unknown_member_on_struct = {
463 /* expect+1: error: type 'struct point' does not have member 'member' [101] */
464 .member[0][0].member = 4,
465 };
466
467 struct point unknown_member_on_scalar = {
468 /* expect+1: error: syntax error 'scalar type cannot use designator' [249] */
469 .x.y.z = 5,
470 };
471
472 struct {
473 int:16;
474 /* expect+2: warning: 'struct <unnamed>' has no named members [65] */
475 /* expect+1: error: cannot initialize struct/union with no named member [179] */
476 } struct_with_only_unnamed_members = {
477 123,
478 };
479
480 union {
481 int:16;
482 /* expect+2: warning: 'union <unnamed>' has no named members [65] */
483 /* expect+1: error: cannot initialize struct/union with no named member [179] */
484 } union_with_only_unnamed_members = {
485 123,
486 };
487
488 int designator_for_scalar = {
489 /* expect+1: error: syntax error 'scalar type cannot use designator' [249] */
490 .value = 3,
491 };
492
493 struct point member_designator_for_scalar_in_struct = {
494 /* expect+1: error: syntax error 'scalar type cannot use designator' [249] */
495 { .x = 3 },
496 };
497 struct point subscript_designator_for_scalar_in_struct = {
498 /* expect+1: error: syntax error 'designator '[...]' is only for arrays' [249] */
499 { [1] = 4 },
500 };
501
502
503 /* Seen in pcidevs_data.h, variable 'pci_words'. */
504 const char string_initialized_with_braced_literal[] = {
505 "initializer",
506 };
507
508 // An array of unknown size containing strings.
509 char weekday_names[][4] = {
510 "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
511 };
512
513 /* nested struct/union initialization */
514 struct outer {
515 int i;
516 char c;
517 union inner {
518 short us;
519 char uc;
520 } u;
521 char *s;
522 } struct_containing_union[] = {
523 {
524 .s = "foo",
525 .c = 'b',
526 .u = {
527 .uc = 'c'
528 }
529 },
530 {
531 .i = 1,
532 .c = 'a',
533 .u = {
534 .us = 2
535 }
536 },
537 };
538
539 /*
540 * The expansion of the offsetof macro may dereference a null pointer.
541 * Such expressions are allowed in initializers for objects with
542 * static duration.
543 */
544 struct offset_and_data {
545 unsigned long offset;
546 unsigned long data;
547 };
548
549 struct offset_and_data offset_and_data = {
550 (unsigned long)&(((struct offset_and_data *)0)->data),
551 0,
552 };
553
554 // The size of the array is determined by the maximum index, not by the last
555 // one mentioned.
556 int arr_11[] = { [10] = 10, [0] = 0 };
557 /* expect+1: error: negative array dimension (-11) [20] */
558 typedef int ctassert_11[-(int)(sizeof(arr_11) / sizeof(arr_11[0]))];
559
560 // Without an explicit subscript designator, the subscript counts up.
561 int arr_3[] = { [1] = 1, [0] = 0, 1, 2 };
562 /* expect+1: error: negative array dimension (-3) [20] */
563 typedef int ctassert_3[-(int)(sizeof(arr_3) / sizeof(arr_3[0]))];
564
565
566 // C99 struct initialization using designators.
567 struct {
568 int i;
569 char *s;
570 } struct_array[] = {
571 {
572 .i = 2,
573 },
574 {
575 .s = "foo"
576 },
577 {
578 .i = 1,
579 .s = "bar"
580 },
581 {
582 .s = "foo",
583 .i = -1
584 },
585 };
586
587 // Ensure that deeply nested structs can be designated in an initializer.
588 int
589 init_deeply_nested_struct(void)
590 {
591 struct rgb {
592 unsigned red;
593 unsigned green;
594 unsigned blue;
595 };
596
597 struct hobbies {
598 unsigned dancing: 1;
599 unsigned running: 1;
600 unsigned swimming: 1;
601 };
602
603 struct person {
604 struct hobbies hobbies;
605 struct rgb favorite_color;
606 };
607
608 struct city {
609 struct person mayor;
610 };
611
612 struct state {
613 struct city capital;
614 };
615
616 struct state st = {
617 .capital.mayor.hobbies.dancing = 1,
618 .capital.mayor.favorite_color.green = 0xFF,
619 .capital.mayor.favorite_color.red = 0xFF,
620 };
621 return st.capital.mayor.favorite_color.red;
622 }
623
624 struct {
625 int i[10];
626 char *s;
627 } struct_array_with_inner_array[] = {
628 {
629 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 },
630 "foo"
631 },
632 };
633
634 struct {
635 int type;
636 union {
637 char b[20];
638 short s[10];
639 long l[5];
640 } data;
641 } array_in_union_in_struct = {
642 .type = 3,
643 .data.l[0] = 4
644 };
645
646 // Somewhere between 2005.12.24.20.47.56 and 2006.12.19.19.06.44, lint could
647 // not initialize named members, see PR bin/20264.
648 union {
649 char *p;
650 int a[1];
651 } array_in_union = {
652 .a = { 7 }
653 };
654
655 /*
656 * Initialization of a nested struct, in which some parts are initialized
657 * from non-constant expressions of the inner struct type.
658 *
659 * In C99, 6.7.8p13 describes exactly this case.
660 */
661 void
662 init_nested_struct(void)
663 {
664
665 typedef enum O1 {
666 O1C = 101
667 } O1;
668 typedef enum O2 {
669 O2C = 102
670 } O2;
671 typedef enum O3 {
672 O3C = 103
673 } O3;
674 typedef enum I1 {
675 I1C = 201
676 } I1;
677 typedef enum I2 {
678 I2C = 202
679 } I2;
680
681 struct Inner1 {
682 I1 i1;
683 };
684
685 struct Outer3Inner1 {
686 O1 o1;
687 struct Inner1 inner;
688 O3 o3;
689 };
690
691 struct Inner1 inner1 = {
692 I1C
693 };
694 struct Outer3Inner1 o3i1 = {
695 O1C,
696 inner1,
697 O3C
698 };
699
700 O1 o1 = o3i1.o1;
701
702 struct Inner2 {
703 I1 i1;
704 I2 i2;
705 };
706
707 struct Outer3Inner2 {
708 O1 o1;
709 struct Inner2 inner;
710 O3 o3;
711 };
712
713 struct Inner2 inner2 = {
714 I1C,
715 I2C
716 };
717 struct Outer3Inner2 o3i2 = {
718 O1C,
719 inner2,
720 O3C
721 };
722 o1 = o3i2.o1;
723
724 /*
725 * For static storage duration, each initializer expression must be a
726 * constant expression.
727 */
728 static struct Inner2 inner3_static = {
729 I1C,
730 I2C
731 };
732 static struct Outer3Inner2 o3i2_static = {
733 O1C,
734 /* expect+1: error: non-constant initializer [177] */
735 inner3_static,
736 O3C
737 };
738 }
739