]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c: pedwarn on flexible array member initialization with {} for C23+ [PR119350]
authorJakub Jelinek <jakub@redhat.com>
Wed, 19 Mar 2025 18:21:38 +0000 (19:21 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Wed, 19 Mar 2025 18:21:38 +0000 (19:21 +0100)
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  <jakub@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
gcc/testsuite/gcc.dg/pr119350-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/pr119350-2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/pr119350-3.c [new file with mode: 0644]

index 1a39cbb20090d922f6f71de2c914694aa2fb0473..71782bc42d2456cef78576e7123e175f8eb76b3f 100644 (file)
@@ -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 (file)
index 0000000..75ab290
--- /dev/null
@@ -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 (file)
index 0000000..ddb3502
--- /dev/null
@@ -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 (file)
index 0000000..20c2b56
--- /dev/null
@@ -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" } */