Hi!

Even in C23/C2Y any initialization of flexible array member is still
invalid, so we should emit a pedwarn on it.  But we no longer do for
initialization with {}.  The reason is that for C17 and earlier,
we already emitted a pedwarn on the {} initializer and so emitting
another pedwarn on the flexible array member initialization would
be diagnosing the same thing multiple times.

In C23 we no longer pedwarn on {}, it is standard.
The following patch arranges a pedwarning for that for C23+, so that
at least one pedwarning is emitted.

So that we don't "regress" from C17 to C23 on nested flexible array
member initialization with no -pedantic/-pedantic-errors/-Wpedantic,
the patch emits even the
initialization of flexible array member in a nested context
diagnostic as pedwarn in the {} case, after all, it doesn't cause
much trouble, we just ignore it like before, it wouldn't initialize
anything.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2025-03-19  Jakub Jelinek  <ja...@redhat.com>

        PR c/119350
        * c-typeck.cc (pop_init_level): Don't ignore empty brackets for
        flag_isoc23, still set constructor_type to NULL in that case but
        emit a pedwarn_init in that case.

        * gcc.dg/pr119350-1.c: New test.
        * gcc.dg/pr119350-2.c: New test.
        * gcc.dg/pr119350-3.c: New test.

--- gcc/c/c-typeck.cc.jj        2025-03-12 21:56:44.217767602 +0100
+++ gcc/c/c-typeck.cc   2025-03-19 00:22:34.094330536 +0100
@@ -10274,24 +10274,29 @@ pop_init_level (location_t loc, int impl
       && !TYPE_MAX_VALUE (TYPE_DOMAIN (constructor_type)))
     {
       /* Silently discard empty initializations.  The parser will
-        already have pedwarned for empty brackets.  */
+        already have pedwarned for empty brackets for C17 and earlier.  */
       if (integer_zerop (constructor_unfilled_index))
        constructor_type = NULL_TREE;
-      else
+      if (constructor_type || flag_isoc23)
        {
-         gcc_assert (!TYPE_SIZE (constructor_type));
+         gcc_assert (!constructor_type || !TYPE_SIZE (constructor_type));
 
-         if (constructor_depth > 2)
+         if (constructor_depth <= 2)
+           pedwarn_init (loc, OPT_Wpedantic,
+                         "initialization of a flexible array member");
+         else if (constructor_type)
            error_init (loc, "initialization of flexible array member "
                             "in a nested context");
          else
            pedwarn_init (loc, OPT_Wpedantic,
-                         "initialization of a flexible array member");
+                         "initialization of flexible array member "
+                         "in a nested context");
 
          /* We have already issued an error message for the existence
             of a flexible array member not at the end of the structure.
             Discard the initializer so that we do not die later.  */
-         if (DECL_CHAIN (constructor_fields) != NULL_TREE
+         if (constructor_type
+             && DECL_CHAIN (constructor_fields) != NULL_TREE
              && (!p->type || TREE_CODE (p->type) != UNION_TYPE))
            constructor_type = NULL_TREE;
        }
--- gcc/testsuite/gcc.dg/pr119350-1.c.jj        2025-03-18 21:22:54.450558554 
+0100
+++ gcc/testsuite/gcc.dg/pr119350-1.c   2025-03-18 21:22:54.450558554 +0100
@@ -0,0 +1,14 @@
+/* PR c/119350 */
+/* { dg-do compile } */
+/* { dg-options "-std=c23 -pedantic-errors" } */
+
+struct S { int a; int b[]; };
+struct T { struct S c; };                      /* { dg-error "invalid use of 
structure with flexible array member" } */
+struct S d = { 1, {} };                                /* { dg-error 
"initialization of a flexible array member" } */
+struct S e = { 1, { 2 } };                     /* { dg-error "initialization 
of a flexible array member" } */
+struct S f = { .a = 1, .b = {} };              /* { dg-error "initialization 
of a flexible array member" } */
+struct S g = { .a = 1, .b = { 2 } };           /* { dg-error "initialization 
of a flexible array member" } */
+struct T h = { { 1, {} } };                    /* { dg-error "initialization 
of flexible array member in a nested context" } */
+struct T i = { { 1, { 2 } } };                 /* { dg-error "initialization 
of flexible array member in a nested context" } */
+struct T j = { .c = { .a = 1, .b = {} } };     /* { dg-error "initialization 
of flexible array member in a nested context" } */
+struct T k = { .c = { .a = 1, .b = { 2 } } };  /* { dg-error "initialization 
of flexible array member in a nested context" } */
--- gcc/testsuite/gcc.dg/pr119350-2.c.jj        2025-03-18 21:22:54.450558554 
+0100
+++ gcc/testsuite/gcc.dg/pr119350-2.c   2025-03-19 00:24:33.735762508 +0100
@@ -0,0 +1,14 @@
+/* PR c/119350 */
+/* { dg-do compile } */
+/* { dg-options "-std=c23 -Wpedantic" } */
+
+struct S { int a; int b[]; };
+struct T { struct S c; };                      /* { dg-warning "invalid use of 
structure with flexible array member" } */
+struct S d = { 1, {} };                                /* { dg-warning 
"initialization of a flexible array member" } */
+struct S e = { 1, { 2 } };                     /* { dg-warning "initialization 
of a flexible array member" } */
+struct S f = { .a = 1, .b = {} };              /* { dg-warning "initialization 
of a flexible array member" } */
+struct S g = { .a = 1, .b = { 2 } };           /* { dg-warning "initialization 
of a flexible array member" } */
+struct T h = { { 1, {} } };                    /* { dg-warning "initialization 
of flexible array member in a nested context" } */
+struct T i = { { 1, { 2 } } };                 /* { dg-error "initialization 
of flexible array member in a nested context" } */
+struct T j = { .c = { .a = 1, .b = {} } };     /* { dg-warning "initialization 
of flexible array member in a nested context" } */
+struct T k = { .c = { .a = 1, .b = { 2 } } };  /* { dg-error "initialization 
of flexible array member in a nested context" } */
--- gcc/testsuite/gcc.dg/pr119350-3.c.jj        2025-03-18 21:22:54.451558540 
+0100
+++ gcc/testsuite/gcc.dg/pr119350-3.c   2025-03-19 00:25:10.859275972 +0100
@@ -0,0 +1,14 @@
+/* PR c/119350 */
+/* { dg-do compile } */
+/* { dg-options "-std=c23 -Wc11-c23-compat" } */
+
+struct S { int a; int b[]; };
+struct T { struct S c; };
+struct S d = { 1, {} };                                /* { dg-warning "ISO C 
forbids empty initializer braces before C23" } */
+struct S e = { 1, { 2 } };
+struct S f = { .a = 1, .b = {} };              /* { dg-warning "ISO C forbids 
empty initializer braces before C23" } */
+struct S g = { .a = 1, .b = { 2 } };
+struct T h = { { 1, {} } };                    /* { dg-warning "ISO C forbids 
empty initializer braces before C23" } */
+struct T i = { { 1, { 2 } } };                 /* { dg-error "initialization 
of flexible array member in a nested context" } */
+struct T j = { .c = { .a = 1, .b = {} } };     /* { dg-warning "ISO C forbids 
empty initializer braces before C23" } */
+struct T k = { .c = { .a = 1, .b = { 2 } } };  /* { dg-error "initialization 
of flexible array member in a nested context" } */

        Jakub

Reply via email to