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

Jakub Jelinek <jakub at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |jakub at gcc dot gnu.org
   Last reconfirmed|                            |2020-03-24
           Assignee|unassigned at gcc dot gnu.org      |jakub at gcc dot gnu.org
            Summary|Program result error When   |[8/9/10 Regression] Program
                   |using global object array   |result error When using
                   |(partially initialized with |global object array
                   |a special constructor, and  |(partially initialized with
                   |the rest with the default   |a special constructor, and
                   |constructor)                |the rest with the default
                   |                            |constructor)
   Target Milestone|---                         |8.5
             Status|UNCONFIRMED                 |ASSIGNED
     Ever confirmed|0                           |1

--- Comment #1 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
Untested fix:
--- gcc/varasm.c.jj     2020-01-22 10:19:24.000000000 +0100
+++ gcc/varasm.c        2020-03-24 18:03:08.532690584 +0100
@@ -5152,6 +5152,26 @@ struct oc_local_state {
 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));

Reply via email to