11.11Srillig/*	$NetBSD: init_braces.c,v 1.11 2025/04/12 15:49:49 rillig Exp $	*/
21.1Srillig# 3 "init_braces.c"
31.1Srillig
41.1Srillig/*
51.1Srillig * Test initialization with excess braces around expressions.
61.1Srillig *
71.1Srillig * See also:
81.1Srillig *	C99 6.7.8
91.1Srillig *	C11 6.7.9
101.1Srillig */
111.1Srillig
121.8Srillig/* lint1-extra-flags: -X 351 */
131.8Srillig
141.1Srilligvoid
151.1Srilliginit_int(void)
161.1Srillig{
171.3Srillig	/* gcc-expect+4: error: invalid initializer */
181.3Srillig	/* clang-expect+3: error: array initializer must be an initializer list */
191.9Srillig	/* expect+2: error: {}-enclosed or constant initializer of type 'array[unknown_size] of int' required [181] */
201.2Srillig	/* expect+1: error: empty array declaration for 'num0' [190] */
211.1Srillig	int num0[] = 0;
221.1Srillig	int num1[] = { 1 };
231.1Srillig	/* gcc-expect+2: warning: braces around scalar initializer */
241.1Srillig	/* clang-expect+1: warning: braces around scalar initializer */
251.1Srillig	int num2[] = {{ 1 }};
261.1Srillig	/* gcc-expect+3: warning: braces around scalar initializer */
271.1Srillig	/* gcc-expect+2: warning: braces around scalar initializer */
281.1Srillig	/* clang-expect+1: warning: too many braces around scalar initializer */
291.1Srillig	int num3[] = {{{ 1 }}};
301.1Srillig	/* gcc-expect+5: warning: braces around scalar initializer */
311.1Srillig	/* gcc-expect+4: warning: braces around scalar initializer */
321.1Srillig	/* gcc-expect+3: warning: braces around scalar initializer */
331.1Srillig	/* clang-expect+2: warning: too many braces around scalar initializer */
341.1Srillig	/* clang-expect+1: warning: too many braces around scalar initializer */
351.1Srillig	int num4[] = {{{{ 1 }}}};
361.1Srillig}
371.1Srillig
381.1Srilligvoid
391.1Srilliginit_string(void)
401.1Srillig{
411.1Srillig	char name0[] = "";
421.1Srillig	char name1[] = { "" };
431.1Srillig	/* gcc-expect+5: warning: braces around scalar initializer */
441.1Srillig	/* gcc-expect+4: warning: initialization of 'char' from 'char *' makes integer from pointer without a cast */
451.1Srillig	/* clang-expect+3: warning: incompatible pointer to integer conversion initializing 'char' with an expression of type 'char [1]' */
461.1Srillig	/* clang-expect+2: warning: braces around scalar initializer */
471.11Srillig	/* expect+1: warning: invalid combination of integer 'char' and pointer 'pointer to char' for 'init' [183] */
481.1Srillig	char name2[] = {{ "" }};
491.1Srillig	/* gcc-expect+6: warning: braces around scalar initializer */
501.1Srillig	/* gcc-expect+5: warning: braces around scalar initializer */
511.1Srillig	/* gcc-expect+4: warning: initialization of 'char' from 'char *' makes integer from pointer without a cast */
521.1Srillig	/* clang-expect+3: warning: too many braces around scalar initializer */
531.1Srillig	/* clang-expect+2: warning: incompatible pointer to integer conversion initializing 'char' with an expression of type 'char [1]' */
541.11Srillig	/* expect+1: warning: invalid combination of integer 'char' and pointer 'pointer to char' for 'init' [183] */
551.1Srillig	char name3[] = {{{ "" }}};
561.1Srillig	/* gcc-expect+8: warning: braces around scalar initializer */
571.1Srillig	/* gcc-expect+7: warning: braces around scalar initializer */
581.1Srillig	/* gcc-expect+6: warning: braces around scalar initializer */
591.1Srillig	/* gcc-expect+5: warning: initialization of 'char' from 'char *' makes integer from pointer without a cast */
601.1Srillig	/* clang-expect+4: warning: too many braces around scalar initializer */
611.1Srillig	/* clang-expect+3: warning: too many braces around scalar initializer */
621.1Srillig	/* clang-expect+2: warning: incompatible pointer to integer conversion initializing 'char' with an expression of type 'char [1]' */
631.11Srillig	/* expect+1: warning: invalid combination of integer 'char' and pointer 'pointer to char' for 'init' [183] */
641.1Srillig	char name4[] = {{{{ "" }}}};
651.1Srillig}
661.3Srillig
671.4Srillig/* C11 6.7.2.1p13 */
681.3Srilligunsigned long
691.4Srilliginit_anonymous_struct_and_union(void)
701.3Srillig{
711.3Srillig	struct time {
721.3Srillig		unsigned long ns;
731.3Srillig	};
741.3Srillig
751.3Srillig	struct times {
761.3Srillig		struct time t0;
771.3Srillig		struct time t1;
781.3Srillig	};
791.3Srillig
801.3Srillig	struct outer {
811.3Srillig		union {
821.3Srillig			struct {
831.3Srillig				struct times times;
841.3Srillig			};
851.3Srillig		};
861.3Srillig	};
871.3Srillig
881.3Srillig	struct outer var = {	/* struct outer */
891.4Srillig		{		/* anonymous union */
901.4Srillig			{	/* anonymous struct */
911.3Srillig				.times = {
921.3Srillig					.t0 = { .ns = 0, },
931.3Srillig					.t1 = { .ns = 0, },
941.3Srillig				},
951.3Srillig			},
961.3Srillig		},
971.3Srillig	};
981.3Srillig
991.3Srillig	return var.times.t0.ns;
1001.3Srillig}
1011.6Srillig
1021.7Srillig// Initializers may designate members from unnamed struct/union members.
1031.7Srillig// Example code adapted from jemalloc 5.1.0, jemalloc.c, init_lock.
1041.6Srilligunsigned char
1051.6Srilliginit_unnamed_union(void)
1061.6Srillig{
1071.6Srillig	struct init_unnamed_union {
1081.6Srillig		union {
1091.6Srillig			struct {
1101.6Srillig				struct padded_union {
1111.6Srillig					unsigned char pad1[3];
1121.6Srillig					union {
1131.6Srillig						unsigned char u1;
1141.6Srillig						unsigned char u2;
1151.6Srillig					};
1161.6Srillig					unsigned char pad2[3];
1171.6Srillig				} padded_union;
1181.6Srillig			};
1191.6Srillig		};
1201.6Srillig	};
1211.6Srillig
1221.6Srillig	struct init_unnamed_union var = {
1231.6Srillig		{
1241.6Srillig			{
1251.6Srillig				.padded_union = {
1261.6Srillig					.pad1 = { 0, 0, 0 },
1271.6Srillig					.u1 = 0,
1281.6Srillig					.pad2 = { 0, 0, 0 },
1291.6Srillig				},
1301.6Srillig			}
1311.6Srillig		},
1321.6Srillig	};
1331.6Srillig	return var.padded_union.u1;
1341.6Srillig}
135