This patch treats the GNAT-specific 'Img attribute as a callable entity which
therefore can be renamed as a function.  The prefix of the attribute reference
is an object rather than a subtype, and it is not evaluated at the point of the
renaming declaration.

Executing the following :

   gnatmake -q inst
   inst

must yield:

    12345
    456
   F2 =  456, Flag = TRUE
   F2 =  789, Flag = FALSE

---
with Text_IO; use Text_IO;
procedure Inst is
   generic
      with function F return String;
   procedure Gen;
   procedure Gen is begin
      Put_Line (F);
   end Gen;

   V : Integer;
   procedure Inst_Img is new Gen (V'Img);

   Table : array (Boolean) of Integer := (123, 456);
   Flag : Boolean := False;
   
   function F2 return String;
   function F2 return String renames Table(Flag)'Img;

begin
   V := 12345;
   Inst_Img;

   Table (False) := 789;
   Flag := True;

   Put_Line (Table (Flag)'Img);
   Put_Line ("F2 = " & F2 & ", Flag = " & Boolean'Image (Flag));

   Flag := False;
   Put_Line ("F2 = " & F2 & ", Flag = " & Boolean'Image (Flag));
end Inst;

Tested on x86_64-pc-linux-gnu, committed on trunk

2013-07-08  Ed Schonberg  <schonb...@adacore.com>

        * sem_ch8.adb (Attribute_Renaming): Treat 'Img as an attribute
        that can be renamed as a function.

Index: sem_ch8.adb
===================================================================
--- sem_ch8.adb (revision 200757)
+++ sem_ch8.adb (working copy)
@@ -3318,12 +3318,14 @@
 
       --  This procedure is called in the context of subprogram renaming, and
       --  thus the attribute must be one that is a subprogram. All of those
-      --  have at least one formal parameter, with the singular exception of
-      --  AST_Entry (which is a real oddity, it is odd that this can be renamed
-      --  at all!)
+      --  have at least one formal parameter, with the exceptions of AST_Entry
+      --  (which is a real oddity, it is odd that this can be renamed at all!)
+      --  and the GNAT attribute 'Img, which GNAT treats as renameable.
 
       if not Is_Non_Empty_List (Parameter_Specifications (Spec)) then
-         if Aname /= Name_AST_Entry then
+         if Aname /= Name_AST_Entry
+           and then Aname /= Name_Img
+         then
             Error_Msg_N
               ("subprogram renaming an attribute must have formals", N);
             return;
@@ -3493,11 +3495,21 @@
         and then Etype (Nam) /= RTE (RE_AST_Handler)
       then
          declare
-            P : constant Entity_Id := Prefix (Nam);
+            P : constant Node_Id := Prefix (Nam);
 
          begin
-            Find_Type (P);
+            --  The prefix of 'Img is an object that is evaluated for
+            --  each call of the function that renames it.
 
+            if Aname = Name_Img then
+               Preanalyze_And_Resolve (P);
+
+            --  For all other attribute renamings, the prefix is a subtype.
+
+            else
+               Find_Type (P);
+            end if;
+
             if Is_Tagged_Type (Etype (P)) then
                Ensure_Freeze_Node (Etype (P));
                Append_Freeze_Action (Etype (P), Body_Node);

Reply via email to