The compiler may crash when compiling array aggregates where the
computation of the size produces a very large number that overflows
(possibly producing a small result), such as with an aggregate of a type
that is an array of arrays, where each array range has close to
Integer'Last elements. That can lead to Aggr_Size_OK returning
incorrectly returning True, following on to allocating a very large
array in function Flatten that blows the stack. The size computation
was being performed using type Int, so this was changed to use universal
arithmetic.
Tested on x86_64-pc-linux-gnu, committed on trunk
2019-08-13 Gary Dismukes <dismu...@adacore.com>
gcc/ada/
* exp_aggr.adb (Aggr_Size_OK): Compute the aggregate size using
universal arithmetic, to avoid situations where the size
computation overflows.
gcc/testsuite/
* gnat.dg/aggr26.adb: New testcase.
--- gcc/ada/exp_aggr.adb
+++ gcc/ada/exp_aggr.adb
@@ -344,7 +344,7 @@ package body Exp_Aggr is
Lo : Node_Id;
Hi : Node_Id;
Indx : Node_Id;
- Siz : Int;
+ Size : Uint;
Lov : Uint;
Hiv : Uint;
@@ -468,7 +468,7 @@ package body Exp_Aggr is
Max_Aggr_Size := 5000;
end if;
- Siz := Component_Count (Component_Type (Typ));
+ Size := UI_From_Int (Component_Count (Component_Type (Typ)));
Indx := First_Index (Typ);
while Present (Indx) loop
@@ -538,14 +538,17 @@ package body Exp_Aggr is
return False;
end if;
- Siz := Siz * UI_To_Int (Rng);
- end;
+ -- Compute the size using universal arithmetic to avoid the
+ -- possibility of overflow on very large aggregates.
- if Siz <= 0
- or else Siz > Max_Aggr_Size
- then
- return False;
- end if;
+ Size := Size * Rng;
+
+ if Size <= 0
+ or else Size > Max_Aggr_Size
+ then
+ return False;
+ end if;
+ end;
-- Bounds must be in integer range, for later array construction
--- /dev/null
new file mode 100644
+++ gcc/testsuite/gnat.dg/aggr26.adb
@@ -0,0 +1,10 @@
+-- { dg-do compile }
+
+procedure Aggr26 is
+
+ type Row is array (Positive) of Integer;
+ H : array (Positive) of Row := (others => (others => 0)); -- { dg-warning "\"Storage_Error\" will be raised at run time" }
+
+begin
+ null;
+end Aggr26;