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" } */