There is only one last_field for a structure type, but there might be multiple last_fields for a union type, therefore we should ORed the result of TYPE_INCLUDES_FLEXARRAY for multiple last_fields of a union type.
The patch has been bootstrapped and regression tested on both x86 and aarch64. Okay for trunk and also GCC14? thanks. Qing PR c/120354 gcc/c/ChangeLog: * c-decl.cc (finish_struct): Or the results for TYPE_INCLUDES_FLEXARRAY. gcc/testsuite/ChangeLog: * gcc.dg/pr120354.c: New test. --- gcc/c/c-decl.cc | 9 ++++++--- gcc/testsuite/gcc.dg/pr120354.c | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/pr120354.c diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc index 4733287eaf8..2b72b782fc5 100644 --- a/gcc/c/c-decl.cc +++ b/gcc/c/c-decl.cc @@ -9647,15 +9647,18 @@ finish_struct (location_t loc, tree t, tree fieldlist, tree attributes, DECL_NOT_FLEXARRAY (x) = !is_flexible_array_member_p (is_last_field, x); /* Set TYPE_INCLUDES_FLEXARRAY for the context of x, t. - when x is an array and is the last field. */ + when x is an array and is the last field. + There is only one last_field for a structure type, but there might + be multiple last_fields for a union type, therefore we should ORed + the result for multiple last_fields. */ if (TREE_CODE (TREE_TYPE (x)) == ARRAY_TYPE) TYPE_INCLUDES_FLEXARRAY (t) - = is_last_field && c_flexible_array_member_type_p (TREE_TYPE (x)); + |= is_last_field && c_flexible_array_member_type_p (TREE_TYPE (x)); /* Recursively set TYPE_INCLUDES_FLEXARRAY for the context of x, t when x is an union or record and is the last field. */ else if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (x))) TYPE_INCLUDES_FLEXARRAY (t) - = is_last_field && TYPE_INCLUDES_FLEXARRAY (TREE_TYPE (x)); + |= is_last_field && TYPE_INCLUDES_FLEXARRAY (TREE_TYPE (x)); if (warn_flex_array_member_not_at_end && !is_last_field diff --git a/gcc/testsuite/gcc.dg/pr120354.c b/gcc/testsuite/gcc.dg/pr120354.c new file mode 100644 index 00000000000..6749737a173 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr120354.c @@ -0,0 +1,33 @@ +/* PR120354: Test for -Wflex-array-member-not-at-end on union with + flexible array members. */ +/* { dg-do compile } */ +/* { dg-options "-Wflex-array-member-not-at-end" } */ + +struct P {}; +union L {}; + +union X { + int x[]; + struct P y; +}; + +struct T { + union X x; /* { dg-warning "structure containing a flexible array member is not at the end of another structure" } */ + int plug; +}; + +struct Q { + int len; + int data[]; +}; + +union Y { + struct Q q; + union L y; +}; + +struct S { + union Y y; /* { dg-warning "structure containing a flexible array member is not at the end of another structure" } */ + int plug; +}; + -- 2.43.5