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"?