]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Fix internal error on small array with negative lower bound
authorEric Botcazou <ebotcazou@adacore.com>
Fri, 19 May 2023 07:00:11 +0000 (09:00 +0200)
committerEric Botcazou <ebotcazou@adacore.com>
Fri, 19 May 2023 07:02:17 +0000 (09:02 +0200)
Ada supports arrays with negative indices, although the internal index type
is sizetype like in other languages, which is unsigned.  This means that
negative values are represented by very large numbers, which works with a
bit of care.  This plugs a small loophole in output_constructor_bitfield.

gcc/
* varasm.cc (output_constructor_bitfield): Call tree_to_uhwi instead
of tree_to_shwi on array indices.  Minor tweaks.

gcc/testsuite/
* gnat.dg/specs/array6.ads: New test.

gcc/testsuite/gnat.dg/specs/array6.ads [new file with mode: 0644]
gcc/varasm.cc

diff --git a/gcc/testsuite/gnat.dg/specs/array6.ads b/gcc/testsuite/gnat.dg/specs/array6.ads
new file mode 100644 (file)
index 0000000..72f8824
--- /dev/null
@@ -0,0 +1,14 @@
+-- { dg-do compile }
+
+package Array6 is 
+
+  type Range_Type is range -10 ..  10;
+  type Array_Type is array (Range_Type range <> ) of Short_Short_Integer;
+
+  type Record_Type is record 
+    A : Array_Type(-2..4);
+  end record ;
+
+  Rec : Record_Type := (A => (others => -1));
+
+end Array6;
index 2e1dee46c9fe8d4fc1b621fcea08fc2b52be3ee4..571bb2e2f0eb293b917658d73beaf6e66675c26d 100644 (file)
@@ -5564,19 +5564,18 @@ output_constructor_bitfield (oc_local_state *local, unsigned int bit_offset)
 
   /* Relative index of this element if this is an array component.  */
   HOST_WIDE_INT relative_index
-    = (!local->field
-       ? (local->index
-         ? (tree_to_shwi (local->index)
-            - tree_to_shwi (local->min_index))
-         : local->last_relative_index + 1)
-       : 0);
+    = (local->field
+       ? 0
+       : (local->index
+         ? tree_to_uhwi (local->index) - tree_to_uhwi (local->min_index)
+         : local->last_relative_index + 1));
 
   /* Bit position of this element from the start of the containing
      constructor.  */
   HOST_WIDE_INT constructor_relative_ebitpos
-      = (local->field
-        ? int_bit_position (local->field)
-        : ebitsize * relative_index);
+    = (local->field
+       ? int_bit_position (local->field)
+       : ebitsize * relative_index);
 
   /* Bit position of this element from the start of a possibly ongoing
      outer byte buffer.  */