xref: /netbsd-src/tests/usr.bin/xlint/lint1/init_c99.c (revision 0f4cfb3194727ca0b8e46faf51c9e2ed182e51ed)
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
struct_initialization_via_assignment(any arg)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
initialization_by_braced_string(void)44 initialization_by_braced_string(void)
45 {
46 	any local = { "hello" };
47 	use(&local);
48 }
49 
50 void
initialization_by_redundantly_braced_string(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
initialization_with_too_many_braces(any arg)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
c99_6_7_8_p31_example7(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
ensure_array_type_is_not_modified_during_initialization(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
init_deeply_nested_struct(void)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
init_nested_struct(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