]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
C: Flex array in union followed by a structure field is not reported [PR120354]
authorQing Zhao <qing.zhao@oracle.com>
Wed, 30 Jul 2025 14:49:12 +0000 (14:49 +0000)
committerQing Zhao <qing.zhao@oracle.com>
Wed, 30 Jul 2025 14:49:12 +0000 (14:49 +0000)
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.

(cherry picked from commit 70418e6c0120cfce33ab69628602dfdadbed683a)

gcc/c/c-decl.cc
gcc/testsuite/gcc.dg/pr120354.c [new file with mode: 0644]

index 42e17dcdbf89d0f7bcbd8960d5e95b9678ac86b8..5032ba1377996e28a30819983b18462bb3b57258 100644 (file)
@@ -9665,15 +9665,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 (file)
index 0000000..6749737
--- /dev/null
@@ -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;
+};
+