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

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

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |jsm28 at gcc dot gnu.org,
                   |                            |rguenth at gcc dot gnu.org
           Keywords|                            |accepts-invalid
           Assignee|rguenth at gcc dot gnu.org         |unassigned at gcc dot 
gnu.org
             Status|ASSIGNED                    |NEW

--- Comment #4 from Richard Biener <rguenth at gcc dot gnu.org> ---
So the issue is we do

            /* But record element size in units of the type alignment.  */
            temp.op2 = TREE_OPERAND (ref, 3);
            temp.align = eltype->type_common.align;
            if (! temp.op2)
              temp.op2 = size_binop (EXACT_DIV_EXPR, TYPE_SIZE_UNIT (eltype),
                                     size_int (TYPE_ALIGN_UNIT (eltype)));

and compute EXACT_DIV of 72 (unit size) by 64 (alignment).  That computes
without ICEing but it will result in a badly reconstructed element size, 64,
and thus a badly reconstructed effective offset.  We do this "dance" because
op2 is measured in alignment units of the element type and to reconstruct
the offset we do

tree
array_ref_element_size (tree exp)
{
  tree aligned_size = TREE_OPERAND (exp, 3);
  tree elmt_type = TREE_TYPE (TREE_TYPE (TREE_OPERAND (exp, 0)));
  location_t loc = EXPR_LOCATION (exp);

  /* If a size was specified in the ARRAY_REF, it's the size measured
     in alignment units of the element type.  So multiply by that value.  */
  if (aligned_size)
    {
      /* ??? tree_ssa_useless_type_conversion will eliminate casts to
         sizetype from another type of the same width and signedness.  */
      if (TREE_TYPE (aligned_size) != sizetype)
        aligned_size = fold_convert_loc (loc, sizetype, aligned_size);
      return size_binop_loc (loc, MULT_EXPR, aligned_size,
                             size_int (TYPE_ALIGN_UNIT (elmt_type)));

so there's no TREE_OPERAND (array-ref, 2) that "correctly" represents the
ARRAY_REF and IMHO the fact that we expand it "correctly" is pure luck.

For C arrays the element type has to be aligned so its size is a multiple
of it (thus all elements can be correctly aligned).  And C arrays have no
"padding".

Not sure what to do here, the FE could reject this or the layout would need
to insert padding, but IIRC we reject arrays of overaligned types:

typedef int aligned_int __attribute__((aligned(8)));
aligned_int x[4];
> ./cc1 -quiet t5.c
t5.c:15:1: error: alignment of array elements is greater than element size
   15 | aligned_int x[4];
      | ^~~~~~~~~~~

IMHO this should be expanded to "size of array element is not a multiple
of its alignment"?

Reply via email to