In Ada 2012 it is possible to complete an incomplete type with a record one
of whose components is an anonymous access to task initialized with an
allocator. The analysis of the allocator in the init_proc for the type creates
an anonymous access that requires a master id. This must be obtained from the
added formal of the init_proc, using the master renaming machinery.

Compiling and executing main.adb must yield:

      Yeah

---
with P; use P;
procedure Main is
   THing : T;
begin
   Thing.R.Here;
end;
---
pragma Ada_2012;
package P is
   type T;
   task type RT (Self : not null access T) is
      entry Here;
   end;

   type T is tagged limited record
      R : access RT := new  RT (T'Unrestricted_Access);
      Name : String (1..4) := "Yeah";
   end record;
end P;
---
with Text_IO; use Text_IO;
package body P is
   task body RT is
      begin
         accept  Here do
            Put_Line (Self.Name);
         end;
      end;
end P;

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

2013-04-24  Ed Schonberg  <schonb...@adacore.com>

        * exp_ch4.adb (Expand_N_Allocator):  If the designated object
        has tasks, and the pointer type is an itype that has no master
        id, create a master renaming in the current context, which can
        only be an init_proc.

Index: exp_ch4.adb
===================================================================
--- exp_ch4.adb (revision 198241)
+++ exp_ch4.adb (working copy)
@@ -4577,9 +4577,19 @@
                      --  access type did not get expanded. Salvage it now.
 
                      if not Restriction_Active (No_Task_Hierarchy) then
-                        pragma Assert (Present (Parent (Base_Type (PtrT))));
-                        Expand_N_Full_Type_Declaration
-                          (Parent (Base_Type (PtrT)));
+                        if Present (Parent (Base_Type (PtrT))) then
+                           Expand_N_Full_Type_Declaration
+                             (Parent (Base_Type (PtrT)));
+
+                        else
+                           --  If the type of the allocator is an itype,
+                           --  the master must exist in the context. This
+                           --  is the case when the allocator initializes
+                           --  an access component in an init-proc.
+
+                           pragma Assert (Is_Itype (PtrT));
+                           Build_Master_Renaming (PtrT, N);
+                        end if;
                      end if;
                   end if;
 

Reply via email to