2020-03-25 Jakub Jelinek <jakub@redhat.com>
+ PR middle-end/94303
+ * varasm.c (output_constructor_array_range): If local->index
+ RANGE_EXPR doesn't start at the current location in the constructor,
+ skip needed number of bytes using assemble_zeros or assert we don't
+ go backwards.
+
PR c++/94223
* langhooks.c (lhd_set_decl_assembler_name): Use a static ulong
counter instead of DECL_UID.
static void
output_constructor_array_range (oc_local_state *local)
{
+ /* Perform the index calculation in modulo arithmetic but
+ sign-extend the result because Ada has negative DECL_FIELD_OFFSETs
+ but we are using an unsigned sizetype. */
+ unsigned prec = TYPE_PRECISION (sizetype);
+ offset_int idx = wi::sext (wi::to_offset (TREE_OPERAND (local->index, 0))
+ - wi::to_offset (local->min_index), prec);
+ tree valtype = TREE_TYPE (local->val);
+ HOST_WIDE_INT fieldpos
+ = (idx * wi::to_offset (TYPE_SIZE_UNIT (valtype))).to_short_addr ();
+
+ /* Advance to offset of this element. */
+ if (fieldpos > local->total_bytes)
+ {
+ assemble_zeros (fieldpos - local->total_bytes);
+ local->total_bytes = fieldpos;
+ }
+ else
+ /* Must not go backwards. */
+ gcc_assert (fieldpos == local->total_bytes);
+
unsigned HOST_WIDE_INT fieldsize
= int_size_in_bytes (TREE_TYPE (local->type));