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 <[email protected]>
* 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;