https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88140

Richard Biener <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |jsm28 at gcc dot gnu.org

--- Comment #4 from Richard Biener <rguenth at gcc dot gnu.org> ---
Hmm, no.  But somehow re-building the array type yields TYPE_SIZE == NULL_TREE
rather than TYPE_SIZE == integer_zero_node.

That happens in

Old value = <tree 0x0>
New value = <integer_cst 0x7ffff687ad08>
grokdeclarator (declarator=0x3028700, declspecs=0x30285a0, decl_context=FIELD, 
    initialized=false, width=0x0, decl_attrs=0x7fffffffd518, 
    expr=0x7fffffffd2d0, expr_const_operands=0x7fffffffd2cf, 
    deprecated_state=DEPRECATED_NORMAL)
    at /space/rguenther/src/gcc-sccvn/gcc/c/c-decl.c:6397
6397                        TYPE_SIZE_UNIT (type) = size_zero_node;


                /* The GCC extension for zero-length arrays differs from
                   ISO flexible array members in that sizeof yields
                   zero.  */
                if (size && integer_zerop (size))
                  {
                    gcc_assert (itype);
                    type = build_distinct_type_copy (TYPE_MAIN_VARIANT (type));
                    TYPE_SIZE (type) = bitsize_zero_node;
                    TYPE_SIZE_UNIT (type) = size_zero_node;
                    SET_TYPE_STRUCTURAL_EQUALITY (type);
                  }

and this overrides what layout_type does.

The cleanest fix would be to add a type flag ARRAY_TYPE_ZERO_LENGTH but then
the odd thing is that adjusting the domain to be [0, -1] instead of [0, ]
would probably make layout_type do the same decision?!

For the free-lang-data regression the following is a simple fix which I am
testing now:

diff --git a/gcc/tree.c b/gcc/tree.c
index 39a92464414..a39e611292a 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -5201,6 +5201,15 @@ fld_process_array_type (tree t, tree t2, hash_map<tree,
tree> *map,
       array = build_array_type_1 (t2, TYPE_DOMAIN (t),
                                  TYPE_TYPELESS_STORAGE (t), false);
       TYPE_CANONICAL (array) = TYPE_CANONICAL (t);
+      /* Re-building the array via build_array_type_1 causes the C FE
+         special-handling of zero-length arrays to be dropped.  So
+        we copy back TYPE_SIZE[_UNIT] from the original type here
+        if layout_type decided the type is incomplete.  */
+      if (!TYPE_SIZE (array))
+       {
+         TYPE_SIZE (array) = TYPE_SIZE (t);
+         TYPE_SIZE_UNIT (array) = TYPE_SIZE_UNIT (t);
+       }
       add_tree_to_fld_list (array, fld);
     }
   return array;

Reply via email to