Home | History | Annotate | Line # | Download | only in lint1
      1 /*	$NetBSD: init_c99.c,v 1.5 2025/04/12 15:49:50 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: invalid combination of integer 'char' and pointer 'pointer to char' for 'init' [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