[Ada] Fix small oversight in change to Optimize_Length_Comparison
authorEric Botcazou <ebotcazou@adacore.com>
Sat, 11 Apr 2020 13:40:24 +0000 (15:40 +0200)
committerPierre-Marie de Rodat <derodat@adacore.com>
Wed, 17 Jun 2020 08:14:02 +0000 (04:14 -0400)
2020-06-17  Eric Botcazou  <ebotcazou@adacore.com>

gcc/ada/

* exp_ch4.adb (Optimize_Length_Comparison): Make sure the base
types are the same when comparing Y'Last and X'Last directly.

gcc/ada/exp_ch4.adb

index 42979975721e8df4225bdad6c0d5e01dd338b70a..7ecc9c3c923a7d33863ad5ec3f313184a432c913 100644 (file)
@@ -14052,6 +14052,17 @@ package body Exp_Ch4 is
          Set_Expressions (Left, New_List (New_Copy (Index (1))));
       end if;
 
+      --  Build the Last reference we will use
+
+      Right :=
+        Make_Attribute_Reference (Loc,
+          Prefix         => New_Occurrence_Of (Ent (1), Loc),
+          Attribute_Name => Name_Last);
+
+      if Present (Index (1)) then
+         Set_Expressions (Right, New_List (New_Copy (Index (1))));
+      end if;
+
       --  If general value case, then do the addition of (n - 1), and
       --  also add the needed conversions to type Long_Long_Integer.
 
@@ -14083,16 +14094,27 @@ package body Exp_Ch4 is
                Analyze (Left);
                Analyze (Y_First);
 
-               --  If X'First = Y'First, rewrite it into a direct comparison
-               --  of Y'Last and X'Last without conversions.
+               --  If X'First = Y'First, simplify the above formula into a
+               --  direct comparison of Y'Last and X'Last.
 
                R := Compile_Time_Compare (Left, Y_First, Assume_Valid => True);
 
                if R = EQ then
-                  Left := Y_Last;
-                  Comp := Empty;
+                  Analyze (Right);
+                  Analyze (Y_Last);
 
-               --  Otherwise, use the above formula
+                  --  If the base types are different, convert both operands to
+                  --  Long_Long_Integer, else compare them directly.
+
+                  if Base_Type (Etype (Right)) /= Base_Type (Etype (Y_Last))
+                  then
+                     Left := Convert_To_Long_Long_Integer (Y_Last);
+                  else
+                     Left := Y_Last;
+                     Comp := Empty;
+                  end if;
+
+               --  Otherwise, use the above formula as-is
 
                else
                   Left :=
@@ -14120,17 +14142,6 @@ package body Exp_Ch4 is
          end if;
       end if;
 
-      --  Build the Last reference we will use
-
-      Right :=
-        Make_Attribute_Reference (Loc,
-          Prefix         => New_Occurrence_Of (Ent (1), Loc),
-          Attribute_Name => Name_Last);
-
-      if Present (Index (1)) then
-         Set_Expressions (Right, New_List (New_Copy (Index (1))));
-      end if;
-
       --  If general operand, convert Last reference to Long_Long_Integer
 
       if Present (Comp) then