The previous change has introduced a type consistency issue when the
length comparison boils down to a comparison of the upper bounds.
Tested on x86_64-pc-linux-gnu, committed on trunk
2020-06-17 Eric Botcazou <ebotca...@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
+++ gcc/ada/exp_ch4.adb
@@ -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