diff mbox

[Ada] Compiler crash on large array aggregate

Message ID 20170425105220.GA88408@adacore.com
State New
Headers show

Commit Message

Arnaud Charlet April 25, 2017, 10:52 a.m. UTC
This patch fixes a bug in which the compiler crashes if the number of
subcomponents in an array aggregate is 2**31 or more.

Tested on x86_64-pc-linux-gnu, committed on trunk

2017-04-25  Bob Duff  <duff@adacore.com>

	* exp_aggr.adb (Component_Count): Protect the
	arithmetic from attempting to convert a value >= 2**31 to Int,
	which would otherwise raise Constraint_Error.
diff mbox

Patch

Index: exp_aggr.adb
===================================================================
--- exp_aggr.adb	(revision 247177)
+++ exp_aggr.adb	(working copy)
@@ -352,7 +352,7 @@ 
       --  which hit memory limits in the backend.
 
       function Component_Count (T : Entity_Id) return Nat;
-      --  The limit is applied to the total number of components that the
+      --  The limit is applied to the total number of subcomponents that the
       --  aggregate will have, which is the number of static expressions
       --  that will appear in the flattened array. This requires a recursive
       --  computation of the number of scalar components of the structure.
@@ -399,8 +399,20 @@ 
                   return 0;
 
                else
-                  return
-                    Siz * UI_To_Int (Expr_Value (Hi) - Expr_Value (Lo) + 1);
+                  --  If the number of components is greater than Int'Last,
+                  --  then return Int'Last, so caller will return False (Aggr
+                  --  size is not OK). Otherwise, UI_To_Int will crash.
+
+                  declare
+                     UI : constant Uint :=
+                            Expr_Value (Hi) - Expr_Value (Lo) + 1;
+                  begin
+                     if UI_Is_In_Int_Range (UI) then
+                        return Siz * UI_To_Int (UI);
+                     else
+                        return Int'Last;
+                     end if;
+                  end;
                end if;
             end;