]> 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>
Thu, 29 May 2025 15:59:41 +0000 (15:59 +0000)
committerQing Zhao <qing.zhao@oracle.com>
Fri, 30 May 2025 15:18:35 +0000 (15:18 +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.

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

index 38de96e12876104d6ebb2f8c7eb6bc7a89cbf24b..1008bcaebdc9f4cfb0e7b4895fa46ea9222934b7 100644 (file)
@@ -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 (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;
+};
+