[Ada] Compiler may blow up on array aggregates whose size is very large
authorGary Dismukes <dismukes@adacore.com>
Tue, 13 Aug 2019 08:07:46 +0000 (08:07 +0000)
committerPierre-Marie de Rodat <pmderodat@gcc.gnu.org>
Tue, 13 Aug 2019 08:07:46 +0000 (08:07 +0000)
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

gcc/ada/ChangeLog
gcc/ada/exp_aggr.adb
gcc/testsuite/ChangeLog
gcc/testsuite/gnat.dg/aggr26.adb [new file with mode: 0644]

index ade7e68212d7b6f996e42d2a93b21e14e4dc8d3e..415f950464effa03c3854c5efbe374af0f7276e8 100644 (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
index c944db6b41ebae2bcc4e810ae72a4b5fbce9c411..925d6ae53a45723e1882fb6c97ff898dc644d496 100644 (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
 
index 0c5d9485dfbfab735a250b4ad7ad126d6dd01a62..824fcc8687224c11035eb2537a2709f71146bf98 100644 (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.
diff --git a/gcc/testsuite/gnat.dg/aggr26.adb b/gcc/testsuite/gnat.dg/aggr26.adb
new file mode 100644 (file)
index 0000000..0466473
--- /dev/null
@@ -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;