From 4167b0752365c69e5895b5c8097e7dba34f735f5 Mon Sep 17 00:00:00 2001 From: Gary Dismukes Date: Tue, 13 Aug 2019 08:07:46 +0000 Subject: [PATCH] [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 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 --- gcc/ada/ChangeLog | 6 ++++++ gcc/ada/exp_aggr.adb | 21 ++++++++++++--------- gcc/testsuite/ChangeLog | 4 ++++ gcc/testsuite/gnat.dg/aggr26.adb | 10 ++++++++++ 4 files changed, 32 insertions(+), 9 deletions(-) create mode 100644 gcc/testsuite/gnat.dg/aggr26.adb diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index ade7e68212d..415f950464e 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,9 @@ +2019-08-13 Gary Dismukes + + * 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 * repinfo.adb (List_Scalar_Storage_Order): Modify conditionals diff --git a/gcc/ada/exp_aggr.adb b/gcc/ada/exp_aggr.adb index c944db6b41e..925d6ae53a4 100644 --- a/gcc/ada/exp_aggr.adb +++ b/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 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 0c5d9485dfb..824fcc86872 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2019-08-13 Gary Dismukes + + * gnat.dg/aggr26.adb: New testcase. + 2019-08-13 Yannick Moy * gnat.dg/allocator2.adb, gnat.dg/allocator2.ads: New testcase. diff --git a/gcc/testsuite/gnat.dg/aggr26.adb b/gcc/testsuite/gnat.dg/aggr26.adb new file mode 100644 index 00000000000..0466473d57b --- /dev/null +++ b/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;