/*      $NetBSD: init_braces.c,v 1.11 2025/04/12 15:49:49 rillig Exp $  */
# 3 "init_braces.c"

/*
* Test initialization with excess braces around expressions.
*
* See also:
*      C99 6.7.8
*      C11 6.7.9
*/

/* lint1-extra-flags: -X 351 */

void
init_int(void)
{
       /* gcc-expect+4: error: invalid initializer */
       /* clang-expect+3: error: array initializer must be an initializer list */
       /* expect+2: error: {}-enclosed or constant initializer of type 'array[unknown_size] of int' required [181] */
       /* expect+1: error: empty array declaration for 'num0' [190] */
       int num0[] = 0;
       int num1[] = { 1 };
       /* gcc-expect+2: warning: braces around scalar initializer */
       /* clang-expect+1: warning: braces around scalar initializer */
       int num2[] = {{ 1 }};
       /* gcc-expect+3: warning: braces around scalar initializer */
       /* gcc-expect+2: warning: braces around scalar initializer */
       /* clang-expect+1: warning: too many braces around scalar initializer */
       int num3[] = {{{ 1 }}};
       /* gcc-expect+5: warning: braces around scalar initializer */
       /* gcc-expect+4: warning: braces around scalar initializer */
       /* gcc-expect+3: warning: braces around scalar initializer */
       /* clang-expect+2: warning: too many braces around scalar initializer */
       /* clang-expect+1: warning: too many braces around scalar initializer */
       int num4[] = {{{{ 1 }}}};
}

void
init_string(void)
{
       char name0[] = "";
       char name1[] = { "" };
       /* gcc-expect+5: warning: braces around scalar initializer */
       /* gcc-expect+4: warning: initialization of 'char' from 'char *' makes integer from pointer without a cast */
       /* clang-expect+3: warning: incompatible pointer to integer conversion initializing 'char' with an expression of type 'char [1]' */
       /* clang-expect+2: warning: braces around scalar initializer */
       /* expect+1: warning: invalid combination of integer 'char' and pointer 'pointer to char' for 'init' [183] */
       char name2[] = {{ "" }};
       /* gcc-expect+6: warning: braces around scalar initializer */
       /* gcc-expect+5: warning: braces around scalar initializer */
       /* gcc-expect+4: warning: initialization of 'char' from 'char *' makes integer from pointer without a cast */
       /* clang-expect+3: warning: too many braces around scalar initializer */
       /* clang-expect+2: warning: incompatible pointer to integer conversion initializing 'char' with an expression of type 'char [1]' */
       /* expect+1: warning: invalid combination of integer 'char' and pointer 'pointer to char' for 'init' [183] */
       char name3[] = {{{ "" }}};
       /* gcc-expect+8: warning: braces around scalar initializer */
       /* gcc-expect+7: warning: braces around scalar initializer */
       /* gcc-expect+6: warning: braces around scalar initializer */
       /* gcc-expect+5: warning: initialization of 'char' from 'char *' makes integer from pointer without a cast */
       /* clang-expect+4: warning: too many braces around scalar initializer */
       /* clang-expect+3: warning: too many braces around scalar initializer */
       /* clang-expect+2: warning: incompatible pointer to integer conversion initializing 'char' with an expression of type 'char [1]' */
       /* expect+1: warning: invalid combination of integer 'char' and pointer 'pointer to char' for 'init' [183] */
       char name4[] = {{{{ "" }}}};
}

/* C11 6.7.2.1p13 */
unsigned long
init_anonymous_struct_and_union(void)
{
       struct time {
               unsigned long ns;
       };

       struct times {
               struct time t0;
               struct time t1;
       };

       struct outer {
               union {
                       struct {
                               struct times times;
                       };
               };
       };

       struct outer var = {    /* struct outer */
               {               /* anonymous union */
                       {       /* anonymous struct */
                               .times = {
                                       .t0 = { .ns = 0, },
                                       .t1 = { .ns = 0, },
                               },
                       },
               },
       };

       return var.times.t0.ns;
}

// Initializers may designate members from unnamed struct/union members.
// Example code adapted from jemalloc 5.1.0, jemalloc.c, init_lock.
unsigned char
init_unnamed_union(void)
{
       struct init_unnamed_union {
               union {
                       struct {
                               struct padded_union {
                                       unsigned char pad1[3];
                                       union {
                                               unsigned char u1;
                                               unsigned char u2;
                                       };
                                       unsigned char pad2[3];
                               } padded_union;
                       };
               };
       };

       struct init_unnamed_union var = {
               {
                       {
                               .padded_union = {
                                       .pad1 = { 0, 0, 0 },
                                       .u1 = 0,
                                       .pad2 = { 0, 0, 0 },
                               },
                       }
               },
       };
       return var.padded_union.u1;
}