The first tweak is to change Get_Integer_Type, which is the routine
used by Expand_N_Attribute_Reference to pick a small integer type
for various attributes applied on enumeration types, to use the
"standard" standard integer types instead of the standard integer
types with a specific size. That's consistent with other places
in the front-end doing something equivalent, as the specific size
does not really matter in this case.
The second tweak is to remove an intermediate conversion to the type
Universal_Integer when it occurs between an unchecked conversion and
an inner operand of integer type. The same removal is already done
in the case of a normal conversion and does not change anything.
No functional changes.
Tested on x86_64-pc-linux-gnu, committed on trunk
2020-06-17 Eric Botcazou <ebotca...@adacore.com>
gcc/ada/
* exp_attr.adb (Get_Integer_Type): Use standard types without
a specific size.
* sem_res.adb (Resolve_Unchecked_Type_Conversion): Remove a
redundant intermediate conversion to Universal_Integer.
--- gcc/ada/exp_attr.adb
+++ gcc/ada/exp_attr.adb
@@ -1756,17 +1756,17 @@ package body Exp_Attr is
begin
-- We need to accommodate unsigned values
- if Siz < 8 then
- Int_Typ := Standard_Integer_8;
+ if Siz < RM_Size (Standard_Short_Short_Integer) then
+ Int_Typ := Standard_Short_Short_Integer;
- elsif Siz < 16 then
- Int_Typ := Standard_Integer_16;
+ elsif Siz < RM_Size (Standard_Short_Integer) then
+ Int_Typ := Standard_Short_Integer;
- elsif Siz < 32 then
- Int_Typ := Standard_Integer_32;
+ elsif Siz < RM_Size (Standard_Integer) then
+ Int_Typ := Standard_Integer;
else
- Int_Typ := Standard_Integer_64;
+ Int_Typ := Standard_Long_Long_Integer;
end if;
return Int_Typ;
--- gcc/ada/sem_res.adb
+++ gcc/ada/sem_res.adb
@@ -11998,6 +11998,18 @@ package body Sem_Res is
Resolve (Operand, Opnd_Type);
+ -- If the expression is a conversion to universal integer of an
+ -- an expression with an integer type, then we can eliminate the
+ -- intermediate conversion to universal integer.
+
+ if Nkind (Operand) = N_Type_Conversion
+ and then Entity (Subtype_Mark (Operand)) = Universal_Integer
+ and then Is_Integer_Type (Etype (Expression (Operand)))
+ then
+ Rewrite (Operand, Relocate_Node (Expression (Operand)));
+ Analyze_And_Resolve (Operand);
+ end if;
+
-- In an inlined context, the unchecked conversion may be applied
-- to a literal, in which case its type is the type of the context.
-- (In other contexts conversions cannot apply to literals).