Hi,
the attached Ada testcase trips on the failure of the assertion present on line
6848 in riscv_flatten_aggregate_field:
n_elts = 1 + tree_to_uhwi (TYPE_MAX_VALUE (index))
- tree_to_uhwi (TYPE_MIN_VALUE (index));
gcc_assert (n_elts >= 0);
The problem is that the computation of the number of elements is performed in
HOST_WIDE_INT, which does not reproduce the wraparound of the 32-bit sizetype
index that happens when the low bound is negative and the high bound is not.
The correct computation is the one implemented by tree.cc:array_type_nelts_top
but it is done on trees, while using wide-ints is sufficient in this case.
Tested on riscv32-elf, OK for the mainline?
2026-09-21 Eric Botcazou <[email protected]>
* config/riscv/riscv.cc (riscv_flatten_aggregate_field) <ARRAY_TYPE>:
Perform the computation of the number of elements using the precision
of the index type instead of using HOST_WIDE_INT.
2026-09-21 Eric Botcazou <[email protected]>
* gnat.dg/array44.adb: New test.
--
Eric Botcazoudiff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 9fca2f679a0..1153505bf95 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -6807,7 +6807,6 @@ riscv_flatten_aggregate_field (const_tree type, riscv_aggregate_field *fields,
case ARRAY_TYPE:
{
- HOST_WIDE_INT n_elts;
riscv_aggregate_field subfields[8];
tree index = TYPE_DOMAIN (type);
tree elt_size = TYPE_SIZE_UNIT (TREE_TYPE (type));
@@ -6828,9 +6827,9 @@ riscv_flatten_aggregate_field (const_tree type, riscv_aggregate_field *fields,
|| TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST
|| !index
|| !TYPE_MAX_VALUE (index)
- || !tree_fits_uhwi_p (TYPE_MAX_VALUE (index))
+ || TREE_CODE (TYPE_MAX_VALUE (index)) != INTEGER_CST
|| !TYPE_MIN_VALUE (index)
- || !tree_fits_uhwi_p (TYPE_MIN_VALUE (index))
+ || TREE_CODE (TYPE_MIN_VALUE (index)) != INTEGER_CST
|| !tree_fits_uhwi_p (elt_size))
return -1;
@@ -6843,11 +6842,12 @@ riscv_flatten_aggregate_field (const_tree type, riscv_aggregate_field *fields,
if (n_subfields <= 0)
return -1;
- n_elts = 1 + tree_to_uhwi (TYPE_MAX_VALUE (index))
- - tree_to_uhwi (TYPE_MIN_VALUE (index));
- gcc_assert (n_elts >= 0);
+ const wide_int max = wi::to_wide (TYPE_MAX_VALUE (index));
+ const wide_int min = wi::to_wide (TYPE_MIN_VALUE (index));
+ const wide_int n_elts = max - min + 1;
+ gcc_assert (wi::fits_uhwi_p (n_elts));
- for (HOST_WIDE_INT i = 0; i < n_elts; i++)
+ for (unsigned HOST_WIDE_INT i = 0; i < n_elts.to_uhwi (); i++)
for (int j = 0; j < n_subfields; j++)
{
if (n >= max_aggregate_field)
-- { dg-do compile }
-- { dg-options "-gnata" }
procedure Array44 is
type Buffer_Type is array (Integer range -1 .. 0) of Natural range 0 .. 255;
type U is record
Buffer : Buffer_Type;
end record;
function F (Src : in Buffer_Type) return U is ((Buffer => Src));
Src : constant Buffer_Type := (others => 1);
Dst : constant U := F (Src);
begin
pragma Assert (Dst.Buffer (0) = 1);
end;