1 /* $NetBSD: init_c99.c,v 1.2 2024/06/09 10:27:39 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 /* expect+1: warning: lossy conversion of 3.5 to 'int' [381] */ 294 int c99_6_7_8_p24_example1_i = 3.5; 295 double _Complex c99_6_7_8_p24_example1_c = 5 + 3 * 1.0fi; 296 297 int c99_6_7_8_p25_example2[] = { 1, 3, 5 }; 298 299 int c99_6_7_8_p26_example3a[4][3] = { 300 { 1, 3, 5 }, 301 { 2, 4, 6 }, 302 { 3, 5, 7 }, 303 }; 304 305 int c99_6_7_8_p26_example3b[4][3] = { 306 1, 3, 5, 2, 4, 6, 3, 5, 7 307 }; 308 309 int c99_6_7_8_p27_example4[4][3] = { 310 { 1 }, { 2 }, { 3 }, { 4 } 311 }; 312 313 struct { 314 int a[3], b; 315 } c99_6_7_8_p28_example5[] = { 316 { 1 }, 317 2, 318 }; 319 320 short c99_6_7_8_p29_example6a[4][3][2] = { 321 { 1 }, 322 { 2, 3 }, 323 { 4, 5, 6 }, 324 }; 325 326 short c99_6_7_8_p29_example6b[4][3][2] = { 327 1, 0, 0, 0, 0, 0, 328 2, 3, 0, 0, 0, 0, 329 4, 5, 6, 0, 0, 0, 330 }; 331 332 short c99_6_7_8_p29_example6c[4][3][2] = { 333 { 334 { 1 }, 335 }, 336 { 337 { 2, 3 }, 338 }, 339 { 340 { 4, 5 }, 341 { 6 }, 342 } 343 }; 344 345 void 346 c99_6_7_8_p31_example7(void) 347 { 348 typedef int A[]; 349 350 A a = { 1, 2 }, b = { 3, 4, 5 }; 351 352 /* expect+1: error: negative array dimension (-8) [20] */ 353 typedef int reveal_sizeof_a[-(int)(sizeof(a))]; 354 /* expect+1: error: negative array dimension (-12) [20] */ 355 typedef int reveal_sizeof_b[-(int)(sizeof(b))]; 356 } 357 358 char c99_6_7_8_p32_example8_s1[] = "abc", 359 c99_6_7_8_p32_example8_t1[3] = "abc"; 360 char c99_6_7_8_p32_example8_s2[] = { 'a', 'b', 'c', '\0' }, 361 c99_6_7_8_p32_example8_t2[3] = { 'a', 'b', 'c' }; 362 char *c99_6_7_8_p32_example8_p = "abc"; 363 364 enum { member_one, member_two }; 365 const char *c99_6_7_8_p33_example9[] = { 366 [member_two] = "member two", 367 [member_one] = "member one", 368 }; 369 370 struct { 371 int quot, rem; 372 } c99_6_7_8_p34_example10 = { .quot = 2, .rem = -1 }; 373 374 struct { int a[3], b; } c99_6_7_8_p35_example11[] = 375 { [0].a = {1}, [1].a[0] = 2 }; 376 377 int c99_6_7_8_p36_example12a[16] = { 378 1, 3, 5, 7, 9, [16-5] = 8, 6, 4, 2, 0 379 }; 380 381 int c99_6_7_8_p36_example12b[8] = { 382 1, 3, 5, 7, 9, [8-5] = 8, 6, 4, 2, 0 383 }; 384 385 union { 386 int first_member; 387 void *second_member; 388 unsigned char any_member; 389 } c99_6_7_8_p38_example13 = { .any_member = 42 }; 390 391 392 /* 393 * During initialization of an object of type array of unknown size, the type 394 * information on the symbol is updated in-place. Ensure that this happens on 395 * a copy of the type. 396 * 397 * C99 6.7.8p31 example 7 398 */ 399 void 400 ensure_array_type_is_not_modified_during_initialization(void) 401 { 402 typedef int array_of_unknown_size[]; 403 404 array_of_unknown_size a1 = { 1, 2, 3}; 405 406 switch (4) { 407 case sizeof(array_of_unknown_size): 408 /* expect+1: error: duplicate case '0' in switch [199] */ 409 case 0: 410 case 3: 411 case 4: 412 case 12: 413 break; 414 } 415 416 /* expect+1: error: negative array dimension (-12) [20] */ 417 typedef int reveal_sizeof_a1[-(int)(sizeof(a1))]; 418 } 419 420 struct point unknown_member_name_beginning = { 421 /* expect+1: error: type 'struct point' does not have member 'r' [101] */ 422 .r = 5, 423 .x = 4, 424 .y = 3, 425 }; 426 427 struct point unknown_member_name_middle = { 428 .x = 4, 429 /* expect+1: error: type 'struct point' does not have member 'r' [101] */ 430 .r = 5, 431 .y = 3, 432 }; 433 434 struct point unknown_member_name_end = { 435 .x = 4, 436 .y = 3, 437 /* expect+1: error: type 'struct point' does not have member 'r' [101] */ 438 .r = 5, 439 }; 440 441 union value { 442 int int_value; 443 void *pointer_value; 444 }; 445 446 union value unknown_union_member_name_first = { 447 /* expect+1: error: type 'union value' does not have member 'unknown_value' [101] */ 448 .unknown_value = 4, 449 .int_value = 3, 450 }; 451 452 union value unknown_union_member_name_second = { 453 .int_value = 3, 454 /* expect+1: error: type 'union value' does not have member 'unknown_value' [101] */ 455 .unknown_value = 4, 456 }; 457 458 struct point subscript_designator_on_struct = { 459 /* expect+1: error: syntax error 'designator '[...]' is only for arrays' [249] */ 460 [0] = 3, 461 }; 462 463 struct point unknown_member_on_struct = { 464 /* expect+1: error: type 'struct point' does not have member 'member' [101] */ 465 .member[0][0].member = 4, 466 }; 467 468 struct point unknown_member_on_scalar = { 469 /* expect+1: error: syntax error 'scalar type cannot use designator' [249] */ 470 .x.y.z = 5, 471 }; 472 473 struct { 474 int:16; 475 /* expect+2: warning: 'struct <unnamed>' has no named members [65] */ 476 /* expect+1: error: cannot initialize struct/union with no named member [179] */ 477 } struct_with_only_unnamed_members = { 478 123, 479 }; 480 481 union { 482 int:16; 483 /* expect+2: warning: 'union <unnamed>' has no named members [65] */ 484 /* expect+1: error: cannot initialize struct/union with no named member [179] */ 485 } union_with_only_unnamed_members = { 486 123, 487 }; 488 489 int designator_for_scalar = { 490 /* expect+1: error: syntax error 'scalar type cannot use designator' [249] */ 491 .value = 3, 492 }; 493 494 struct point member_designator_for_scalar_in_struct = { 495 /* expect+1: error: syntax error 'scalar type cannot use designator' [249] */ 496 { .x = 3 }, 497 }; 498 struct point subscript_designator_for_scalar_in_struct = { 499 /* expect+1: error: syntax error 'designator '[...]' is only for arrays' [249] */ 500 { [1] = 4 }, 501 }; 502 503 504 /* Seen in pcidevs_data.h, variable 'pci_words'. */ 505 const char string_initialized_with_braced_literal[] = { 506 "initializer", 507 }; 508 509 // An array of unknown size containing strings. 510 char weekday_names[][4] = { 511 "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" 512 }; 513 514 /* nested struct/union initialization */ 515 struct outer { 516 int i; 517 char c; 518 union inner { 519 short us; 520 char uc; 521 } u; 522 char *s; 523 } struct_containing_union[] = { 524 { 525 .s = "foo", 526 .c = 'b', 527 .u = { 528 .uc = 'c' 529 } 530 }, 531 { 532 .i = 1, 533 .c = 'a', 534 .u = { 535 .us = 2 536 } 537 }, 538 }; 539 540 /* 541 * The expansion of the offsetof macro may dereference a null pointer. 542 * Such expressions are allowed in initializers for objects with 543 * static duration. 544 */ 545 struct offset_and_data { 546 unsigned long offset; 547 unsigned long data; 548 }; 549 550 struct offset_and_data offset_and_data = { 551 (unsigned long)&(((struct offset_and_data *)0)->data), 552 0, 553 }; 554 555 // The size of the array is determined by the maximum index, not by the last 556 // one mentioned. 557 int arr_11[] = { [10] = 10, [0] = 0 }; 558 /* expect+1: error: negative array dimension (-11) [20] */ 559 typedef int ctassert_11[-(int)(sizeof(arr_11) / sizeof(arr_11[0]))]; 560 561 // Without an explicit subscript designator, the subscript counts up. 562 int arr_3[] = { [1] = 1, [0] = 0, 1, 2 }; 563 /* expect+1: error: negative array dimension (-3) [20] */ 564 typedef int ctassert_3[-(int)(sizeof(arr_3) / sizeof(arr_3[0]))]; 565 566 567 // C99 struct initialization using designators. 568 struct { 569 int i; 570 char *s; 571 } struct_array[] = { 572 { 573 .i = 2, 574 }, 575 { 576 .s = "foo" 577 }, 578 { 579 .i = 1, 580 .s = "bar" 581 }, 582 { 583 .s = "foo", 584 .i = -1 585 }, 586 }; 587 588 // Ensure that deeply nested structs can be designated in an initializer. 589 int 590 init_deeply_nested_struct(void) 591 { 592 struct rgb { 593 unsigned red; 594 unsigned green; 595 unsigned blue; 596 }; 597 598 struct hobbies { 599 unsigned dancing: 1; 600 unsigned running: 1; 601 unsigned swimming: 1; 602 }; 603 604 struct person { 605 struct hobbies hobbies; 606 struct rgb favorite_color; 607 }; 608 609 struct city { 610 struct person mayor; 611 }; 612 613 struct state { 614 struct city capital; 615 }; 616 617 struct state st = { 618 .capital.mayor.hobbies.dancing = 1, 619 .capital.mayor.favorite_color.green = 0xFF, 620 .capital.mayor.favorite_color.red = 0xFF, 621 }; 622 return st.capital.mayor.favorite_color.red; 623 } 624 625 struct { 626 int i[10]; 627 char *s; 628 } struct_array_with_inner_array[] = { 629 { 630 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }, 631 "foo" 632 }, 633 }; 634 635 struct { 636 int type; 637 union { 638 char b[20]; 639 short s[10]; 640 long l[5]; 641 } data; 642 } array_in_union_in_struct = { 643 .type = 3, 644 .data.l[0] = 4 645 }; 646 647 // Somewhere between 2005.12.24.20.47.56 and 2006.12.19.19.06.44, lint could 648 // not initialize named members, see PR bin/20264. 649 union { 650 char *p; 651 int a[1]; 652 } array_in_union = { 653 .a = { 7 } 654 }; 655 656 /* 657 * Initialization of a nested struct, in which some parts are initialized 658 * from non-constant expressions of the inner struct type. 659 * 660 * In C99, 6.7.8p13 describes exactly this case. 661 */ 662 void 663 init_nested_struct(void) 664 { 665 666 typedef enum O1 { 667 O1C = 101 668 } O1; 669 typedef enum O2 { 670 O2C = 102 671 } O2; 672 typedef enum O3 { 673 O3C = 103 674 } O3; 675 typedef enum I1 { 676 I1C = 201 677 } I1; 678 typedef enum I2 { 679 I2C = 202 680 } I2; 681 682 struct Inner1 { 683 I1 i1; 684 }; 685 686 struct Outer3Inner1 { 687 O1 o1; 688 struct Inner1 inner; 689 O3 o3; 690 }; 691 692 struct Inner1 inner1 = { 693 I1C 694 }; 695 struct Outer3Inner1 o3i1 = { 696 O1C, 697 inner1, 698 O3C 699 }; 700 701 O1 o1 = o3i1.o1; 702 703 struct Inner2 { 704 I1 i1; 705 I2 i2; 706 }; 707 708 struct Outer3Inner2 { 709 O1 o1; 710 struct Inner2 inner; 711 O3 o3; 712 }; 713 714 struct Inner2 inner2 = { 715 I1C, 716 I2C 717 }; 718 struct Outer3Inner2 o3i2 = { 719 O1C, 720 inner2, 721 O3C 722 }; 723 o1 = o3i2.o1; 724 725 /* 726 * For static storage duration, each initializer expression must be a 727 * constant expression. 728 */ 729 static struct Inner2 inner3_static = { 730 I1C, 731 I2C 732 }; 733 static struct Outer3Inner2 o3i2_static = { 734 O1C, 735 /* expect+1: error: non-constant initializer [177] */ 736 inner3_static, 737 O3C 738 }; 739 } 740