]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Fix PR ada/98230
authorEd Schonberg <schonberg@adacore.com>
Thu, 10 Dec 2020 21:26:57 +0000 (22:26 +0100)
committerEric Botcazou <ebotcazou@adacore.com>
Thu, 10 Dec 2020 21:31:04 +0000 (22:31 +0100)
It's a rather curious malfunction of the 'Mod attribute applied to the
variable of a loop whose upper bound is dynamic.

gcc/ada/ChangeLog:
PR ada/98230
* exp_attr.adb (Expand_N_Attribute_Reference, case Mod): Use base
type of argument to obtain static bound and required size.

gcc/testsuite/ChangeLog:
* gnat.dg/modular6.adb: New test.

gcc/ada/exp_attr.adb
gcc/testsuite/gnat.dg/modular6.adb [new file with mode: 0644]

index 4057a36dc11c87ed767edcb404d1f14e6d6d7f4a..344bb2dcd95f3787317916815285244fa44d60de 100644 (file)
@@ -4513,13 +4513,15 @@ package body Exp_Attr is
 
       when Attribute_Mod => Mod_Case : declare
          Arg  : constant Node_Id := Relocate_Node (First (Exprs));
-         Hi   : constant Node_Id := Type_High_Bound (Etype (Arg));
+         Hi   : constant Node_Id := Type_High_Bound (Base_Type (Etype (Arg)));
          Modv : constant Uint    := Modulus (Btyp);
 
       begin
 
          --  This is not so simple. The issue is what type to use for the
-         --  computation of the modular value.
+         --  computation of the modular value. In addition we need to use
+         --  the base type as above to retrieve a static bound for the
+         --  comparisons that follow.
 
          --  The easy case is when the modulus value is within the bounds
          --  of the signed integer type of the argument. In this case we can
diff --git a/gcc/testsuite/gnat.dg/modular6.adb b/gcc/testsuite/gnat.dg/modular6.adb
new file mode 100644 (file)
index 0000000..f0f1c80
--- /dev/null
@@ -0,0 +1,15 @@
+-- { dg-do compile }
+
+with Ada.Text_IO; use Ada.Text_IO;
+
+procedure Modular6 is
+   Max : Integer := 0;
+   
+   type Modulus is mod 3;
+begin
+   Max := 30;
+   
+   for N in 1 .. Max loop
+      Put_Line("N: " & Integer'Image(N) & " Modulus:    " & Integer'Image(Modulus'Modulus) & " Mod:" & Modulus'Image(Modulus'Mod(N)));
+   end loop;
+end;