gcc/c/ChangeLog:

        * c-decl.cc (finish_struct): Change errors to pedwarns for the cases
        flexible array members in union or alone in structures.

gcc/cp/ChangeLog:

        * class.cc (diagnose_flexarrays): Change error to pdewarn for the case
        flexible array members alone in structures.
        * decl.cc (grokdeclarator): Change error to pdewarn for the case
        flexible array members in unions.

gcc/ChangeLog:

        * stor-layout.cc (place_union_field): Use zero sizes for flexible array
        member fields.
---
 gcc/c/c-decl.cc    | 16 +++++-----------
 gcc/cp/class.cc    | 11 ++++++++---
 gcc/cp/decl.cc     |  7 +++----
 gcc/stor-layout.cc |  9 +++++++--
 4 files changed, 23 insertions(+), 20 deletions(-)

diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc
index 345090dae38b..947f3cd589eb 100644
--- a/gcc/c/c-decl.cc
+++ b/gcc/c/c-decl.cc
@@ -9471,11 +9471,8 @@ finish_struct (location_t loc, tree t, tree fieldlist, 
tree attributes,
       if (flexible_array_member_type_p (TREE_TYPE (x)))
        {
          if (TREE_CODE (t) == UNION_TYPE)
-           {
-             error_at (DECL_SOURCE_LOCATION (x),
-                       "flexible array member in union");
-             TREE_TYPE (x) = error_mark_node;
-           }
+           pedwarn (DECL_SOURCE_LOCATION (x), OPT_Wpedantic,
+                    "flexible array member in union is a GCC extension");
          else if (!is_last_field)
            {
              error_at (DECL_SOURCE_LOCATION (x),
@@ -9483,12 +9480,9 @@ finish_struct (location_t loc, tree t, tree fieldlist, 
tree attributes,
              TREE_TYPE (x) = error_mark_node;
            }
          else if (!saw_named_field)
-           {
-             error_at (DECL_SOURCE_LOCATION (x),
-                       "flexible array member in a struct with no named "
-                       "members");
-             TREE_TYPE (x) = error_mark_node;
-           }
+           pedwarn (DECL_SOURCE_LOCATION (x), OPT_Wpedantic,
+                    "flexible array member in a struct with no named "
+                    "members is a GCC extension");
        }
 
       if (pedantic && TREE_CODE (t) == RECORD_TYPE
diff --git a/gcc/cp/class.cc b/gcc/cp/class.cc
index 5f258729940b..0c8afb72550f 100644
--- a/gcc/cp/class.cc
+++ b/gcc/cp/class.cc
@@ -7624,6 +7624,7 @@ diagnose_flexarrays (tree t, const flexmems_t *fmem)
   bool diagd = false;
 
   const char *msg = 0;
+  const char *msg_fam = 0;
 
   if (TYPE_DOMAIN (TREE_TYPE (fmem->array)))
     {
@@ -7649,15 +7650,19 @@ diagnose_flexarrays (tree t, const flexmems_t *fmem)
       if (fmem->after[0])
        msg = G_("flexible array member %qD not at end of %q#T");
       else if (!fmem->first)
-       msg = G_("flexible array member %qD in an otherwise empty %q#T");
+       msg_fam = G_("flexible array member %qD in an otherwise"
+                    " empty %q#T is a GCC extension");
 
-      if (msg)
+      if (msg || msg_fam)
        {
          location_t loc = DECL_SOURCE_LOCATION (fmem->array);
          diagd = true;
 
          auto_diagnostic_group d;
-         error_at (loc, msg, fmem->array, t);
+         if (msg)
+           error_at (loc, msg, fmem->array, t);
+         else
+           pedwarn (loc, OPT_Wpedantic, msg_fam, fmem->array, t);
 
          /* In the unlikely event that the member following the flexible
             array member is declared in a different class, or the member
diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
index 65ab64885ff8..9a91c6f80da1 100644
--- a/gcc/cp/decl.cc
+++ b/gcc/cp/decl.cc
@@ -14566,10 +14566,9 @@ grokdeclarator (const cp_declarator *declarator,
            if (ctype
                && (TREE_CODE (ctype) == UNION_TYPE
                    || TREE_CODE (ctype) == QUAL_UNION_TYPE))
-             {
-               error_at (id_loc, "flexible array member in union");
-               type = error_mark_node;
-             }
+             pedwarn (id_loc, OPT_Wpedantic,
+                      "flexible array member in union is a GCC extension");
+
            else
              {
                /* Array is a flexible member.  */
diff --git a/gcc/stor-layout.cc b/gcc/stor-layout.cc
index e34be19689c0..10c0809914cd 100644
--- a/gcc/stor-layout.cc
+++ b/gcc/stor-layout.cc
@@ -1245,13 +1245,18 @@ place_union_field (record_layout_info rli, tree field)
       && TYPE_TYPELESS_STORAGE (TREE_TYPE (field)))
     TYPE_TYPELESS_STORAGE (rli->t) = 1;
 
+  /* We might see a flexible array member field (with no DECL_SIZE_UNIT), use
+     zero size for such field.  */
+  tree field_size_unit = DECL_SIZE_UNIT (field)
+                        ? DECL_SIZE_UNIT (field)
+                        : build_int_cst (sizetype, 0);
   /* We assume the union's size will be a multiple of a byte so we don't
      bother with BITPOS.  */
   if (TREE_CODE (rli->t) == UNION_TYPE)
-    rli->offset = size_binop (MAX_EXPR, rli->offset, DECL_SIZE_UNIT (field));
+    rli->offset = size_binop (MAX_EXPR, rli->offset, field_size_unit);
   else if (TREE_CODE (rli->t) == QUAL_UNION_TYPE)
     rli->offset = fold_build3 (COND_EXPR, sizetype, DECL_QUALIFIER (field),
-                              DECL_SIZE_UNIT (field), rli->offset);
+                              field_size_unit, rli->offset);
 }
 
 /* A bitfield of SIZE with a required access alignment of ALIGN is allocated
-- 
2.31.1

Reply via email to