[Ada] Fix expansion of operations on nonbinary modular types
authorEd Schonberg <schonberg@adacore.com>
Tue, 9 Oct 2018 15:05:59 +0000 (15:05 +0000)
committerPierre-Marie de Rodat <pmderodat@gcc.gnu.org>
Tue, 9 Oct 2018 15:05:59 +0000 (15:05 +0000)
2018-10-09  Ed Schonberg  <schonberg@adacore.com>

gcc/ada/

* exp_ch4.adb (Expand_Modular_Op): When expanding an operation
on nonbinary modular types, convert the opersnds to an integer
type that is large enough to hold the modulus of the type, which
may be larger than Integer'Last.

From-SVN: r264973

gcc/ada/ChangeLog
gcc/ada/exp_ch4.adb

index f95316d554dbbb9827e9f26c65ded45ebedba963..bad846033564111a17d7d36f4b894e5cad747021 100644 (file)
@@ -1,3 +1,10 @@
+2018-10-09  Ed Schonberg  <schonberg@adacore.com>
+
+       * exp_ch4.adb (Expand_Modular_Op): When expanding an operation
+       on nonbinary modular types, convert the opersnds to an integer
+       type that is large enough to hold the modulus of the type, which
+       may be larger than Integer'Last.
+
 2018-10-09  Ed Schonberg  <schonberg@adacore.com>
 
        * exp_unst.adb (Unnest_Subprogram):  When an uplevel reference
index a7aee9fcacf2eb6ad26a0be7dc126868c728dbdb..ace501b815acc8bfbf9b3150961230e8bec52586 100644 (file)
@@ -4067,6 +4067,8 @@ package body Exp_Ch4 is
          Op_Expr  : constant Node_Id := New_Op_Node (Nkind (N), Loc);
          Mod_Expr : constant Node_Id := New_Op_Node (N_Op_Mod, Loc);
 
+         Target_Type   : Entity_Id;
+
       begin
          --  Convert nonbinary modular type operands into integer values. Thus
          --  we avoid never-ending loops expanding them, and we also ensure
@@ -4083,11 +4085,21 @@ package body Exp_Ch4 is
               Unchecked_Convert_To (Standard_Integer, Op_Expr));
 
          else
+            --  If the modulus of the type is larger than Integer'Last
+            --  use a larger type for the operands, to prevent spurious
+            --  constraint errors on large legal literals of the type.
+
+            if Modulus (Etype (N)) > UI_From_Int (Int (Integer'Last)) then
+               Target_Type := Standard_Long_Integer;
+            else
+               Target_Type := Standard_Integer;
+            end if;
+
             Set_Left_Opnd (Op_Expr,
-              Unchecked_Convert_To (Standard_Integer,
+              Unchecked_Convert_To (Target_Type,
                 New_Copy_Tree (Left_Opnd (N))));
             Set_Right_Opnd (Op_Expr,
-              Unchecked_Convert_To (Standard_Integer,
+              Unchecked_Convert_To (Target_Type,
                 New_Copy_Tree (Right_Opnd (N))));
 
             --  Link this node to the tree to analyze it