[Ada] Compiler may blow up on array aggregates whose size is very large

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.

2019-08-13  Gary Dismukes  <dismukes@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.

From-SVN: r274348
This commit is contained in:
Gary Dismukes 2019-08-13 08:07:46 +00:00 committed by Pierre-Marie de Rodat
parent 6aaab5081f
commit 4167b07523
4 changed files with 32 additions and 9 deletions

View File

@ -1,3 +1,9 @@
2019-08-13 Gary Dismukes <dismukes@adacore.com>
* exp_aggr.adb (Aggr_Size_OK): Compute the aggregate size using
universal arithmetic, to avoid situations where the size
computation overflows.
2019-08-13 Justin Squirek <squirek@adacore.com>
* repinfo.adb (List_Scalar_Storage_Order): Modify conditionals

View File

@ -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

View File

@ -1,3 +1,7 @@
2019-08-13 Gary Dismukes <dismukes@adacore.com>
* gnat.dg/aggr26.adb: New testcase.
2019-08-13 Yannick Moy <moy@adacore.com>
* gnat.dg/allocator2.adb, gnat.dg/allocator2.ads: New testcase.

View File

@ -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;