https://gcc.gnu.org/g:70418e6c0120cfce33ab69628602dfdadbed683a

commit r16-1018-g70418e6c0120cfce33ab69628602dfdadbed683a
Author: Qing Zhao <qing.z...@oracle.com>
Date:   Thu May 29 15:59:41 2025 +0000

    C: Flex array in union followed by a structure field is not reported 
[PR120354]
    
    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.
    
            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.

Diff:
---
 gcc/c/c-decl.cc                 |  9 ++++++---
 gcc/testsuite/gcc.dg/pr120354.c | 33 +++++++++++++++++++++++++++++++++
 2 files changed, 39 insertions(+), 3 deletions(-)

diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc
index 38de96e12876..1008bcaebdc9 100644
--- a/gcc/c/c-decl.cc
+++ b/gcc/c/c-decl.cc
@@ -9649,15 +9649,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 000000000000..6749737a1737
--- /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;
+};
+

Reply via email to