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).

Reply via email to