https://gcc.gnu.org/g:7ecf468c9a30b5a6da86812b912fe3368437c8b9

commit r15-8446-g7ecf468c9a30b5a6da86812b912fe3368437c8b9
Author: Jakub Jelinek <ja...@redhat.com>
Date:   Wed Mar 19 19:21:38 2025 +0100

    c: pedwarn on flexible array member initialization with {} for C23+ 
[PR119350]
    
    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.
    
    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.

Diff:
---
 gcc/c/c-typeck.cc                 | 17 +++++++++++------
 gcc/testsuite/gcc.dg/pr119350-1.c | 14 ++++++++++++++
 gcc/testsuite/gcc.dg/pr119350-2.c | 14 ++++++++++++++
 gcc/testsuite/gcc.dg/pr119350-3.c | 14 ++++++++++++++
 4 files changed, 53 insertions(+), 6 deletions(-)

diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc
index 1a39cbb20090..71782bc42d24 100644
--- a/gcc/c/c-typeck.cc
+++ b/gcc/c/c-typeck.cc
@@ -10277,24 +10277,29 @@ pop_init_level (location_t loc, int implicit,
       && !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;
        }
diff --git a/gcc/testsuite/gcc.dg/pr119350-1.c 
b/gcc/testsuite/gcc.dg/pr119350-1.c
new file mode 100644
index 000000000000..75ab290b1853
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr119350-1.c
@@ -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" } */
diff --git a/gcc/testsuite/gcc.dg/pr119350-2.c 
b/gcc/testsuite/gcc.dg/pr119350-2.c
new file mode 100644
index 000000000000..ddb3502d6ada
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr119350-2.c
@@ -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" } */
diff --git a/gcc/testsuite/gcc.dg/pr119350-3.c 
b/gcc/testsuite/gcc.dg/pr119350-3.c
new file mode 100644
index 000000000000..20c2b56dd144
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr119350-3.c
@@ -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" } */

Reply via email to