https://gcc.gnu.org/g:7a5f6f764dda359385fb97d8eebe61cab092a200

commit r15-4152-g7a5f6f764dda359385fb97d8eebe61cab092a200
Author: Eric Botcazou <ebotca...@adacore.com>
Date:   Tue Sep 10 12:09:48 2024 +0200

    ada: Avoid dependency on Long_Long_Long_Integer and System.Img_LLLI for 
'Image
    
    When the Image attribute is applied directly to another attribute returning
    Universal_Integer, for example Enum_Rep, it is converted to the equivalent
    of Universal_Integer'Image, which is implemented by Long_Long_Long_Integer
    and thus triggers a dependency on System.Img_LLLI, both being unnecessary
    in most practical cases.
    
    gcc/ada/ChangeLog:
    
            * exp_imgv.adb (Rewrite_Object_Image): When the prefix is a type
            conversion to Universal_Integer, use its expression directly. When
            the prefix is an integer literal with Universal_Integer type, try
            to compute a narrower type.

Diff:
---
 gcc/ada/exp_imgv.adb | 33 +++++++++++++++++++++++++++++----
 1 file changed, 29 insertions(+), 4 deletions(-)

diff --git a/gcc/ada/exp_imgv.adb b/gcc/ada/exp_imgv.adb
index ce052c13c880..b350542fb712 100644
--- a/gcc/ada/exp_imgv.adb
+++ b/gcc/ada/exp_imgv.adb
@@ -2497,18 +2497,43 @@ package body Exp_Imgv is
       Attr_Name : Name_Id;
       Str_Typ   : Entity_Id)
    is
+      P    : Node_Id;
       Ptyp : Entity_Id;
 
    begin
-      Ptyp := Etype (Pref);
+      P    := Pref;
+      Ptyp := Etype (P);
+
+      --  If the type of the prefix is universal integer, which is a very large
+      --  type, try to compute a narrower type. This may happen when the prefix
+      --  itself is an attribute returning universal integer or a named number.
+
+      if Ptyp = Universal_Integer then
+         if Nkind (P) in N_Type_Conversion | N_Unchecked_Type_Conversion then
+            P    := Expression (P);
+            Ptyp := Etype (P);
+
+         elsif Nkind (P) = N_Integer_Literal then
+            declare
+               Val  : constant Uint    := Intval (P);
+               Neg  : constant Boolean := Val < Uint_0;
+               Bits : constant Nat     := Num_Bits (Val) + Boolean'Pos (Neg);
+
+            begin
+               if Bits <= System_Max_Integer_Size then
+                  Ptyp := Integer_Type_For (UI_From_Int (Bits), not Neg);
+               end if;
+            end;
+         end if;
+      end if;
 
       --  If the prefix is a component that depends on a discriminant, then
       --  create an actual subtype for it.
 
-      if Nkind (Pref) = N_Selected_Component then
+      if Nkind (P) = N_Selected_Component then
          declare
             Decl : constant Node_Id :=
-                     Build_Actual_Subtype_Of_Component (Ptyp, Pref);
+                     Build_Actual_Subtype_Of_Component (Ptyp, P);
          begin
             if Present (Decl) then
                Insert_Action (N, Decl);
@@ -2521,7 +2546,7 @@ package body Exp_Imgv is
         Make_Attribute_Reference (Sloc (N),
           Prefix         => New_Occurrence_Of (Ptyp, Sloc (N)),
           Attribute_Name => Attr_Name,
-          Expressions    => New_List (Unchecked_Convert_To (Ptyp, Pref))));
+          Expressions    => New_List (Unchecked_Convert_To (Ptyp, P))));
 
       Analyze_And_Resolve (N, Str_Typ);
    end Rewrite_Object_Image;

Reply via email to