This patch adds switch -gnatd.y to disable the generation of implicit Elaborate_All on a package X when a task body calls a procedure in the same package, and that procedure calls a procedure in another package X.
As documented in the GNAT User Guide, when sources cannot be modified, the recommended solution is the use of restriction No_Entry_Calls_In_Elaboration_Code. This switch provides a way to disable the generation of the implicit Elaborate_All when that restriction is not applicable to the sources. The following test now compiles without errors: with Utils; package body Decls is procedure Put_Val (Arg : Decls.My_Int) is begin Utils.Put_Val(Arg); end Put_Val; task body Lib_Task is begin accept Start; Put_Val (2); -- Utils.Put_Val(Arg); end Lib_Task; function Ident (M : My_Int) return My_Int is begin return M; end Ident; end Decls; package Decls is task Lib_Task is entry Start; end Lib_Task; type My_Int is new Integer; function Ident (M : My_Int) return My_Int; end Decls; with Decls; procedure Main is begin Decls.Lib_Task.Start; end; with Text_IO; package body Utils is procedure Put_Val (Arg : Decls.My_Int) is begin Text_IO.Put_Line (Decls.My_Int'Image (Decls.Ident (Arg))); end Put_Val; end Utils; with Decls; package Utils is procedure Put_Val (Arg : Decls.My_Int); end Utils; Command: gnatmake main.adb -gnatd.y Tested on x86_64-pc-linux-gnu, committed on trunk 2017-09-07 Javier Miranda <mira...@adacore.com> * sem_elab.adb (Check_Task_Activation): Adding switch -gnatd.y to allow disabling the generation of implicit pragma Elaborate_All on task bodies.
Index: debug.adb =================================================================== --- debug.adb (revision 251834) +++ debug.adb (working copy) @@ -115,7 +115,7 @@ -- d.v -- d.w Do not check for infinite loops -- d.x No exception handlers - -- d.y + -- d.y Disable implicit pragma Elaborate_All on task bodies -- d.z Restore previous support for frontend handling of Inline_Always -- d.A Read/write Aspect_Specifications hash table to tree @@ -603,6 +603,12 @@ -- fully compiled and analyzed, they just get eliminated from the -- code generation step. + -- d.y Disable implicit pragma Elaborate_All on task bodies. When a task + -- body calls a procedure in the same package, and that procedure + -- calls a procedure in another package, the static elaboration + -- machinery adds an implicit Elaborate_All on the other package. This + -- switch disables the addition of the implicit pragma in such cases. + -- -- d.z Restore previous front-end support for Inline_Always. In default -- mode, for targets that use the GCC back end, Inline_Always is -- handled by the back end. Use of this switch restores the previous Index: sem_elab.adb =================================================================== --- sem_elab.adb (revision 251834) +++ sem_elab.adb (working copy) @@ -2961,19 +2961,21 @@ Next_Elmt (Elmt); end loop; - -- For tasks declared in the current unit, trace other calls within - -- the task procedure bodies, which are available. + -- For tasks declared in the current unit, trace other calls within the + -- task procedure bodies, which are available. - In_Task_Activation := True; + if not Debug_Flag_Dot_Y then + In_Task_Activation := True; - Elmt := First_Elmt (Intra_Procs); - while Present (Elmt) loop - Ent := Node (Elmt); - Check_Internal_Call_Continue (N, Ent, Enclosing, Ent); - Next_Elmt (Elmt); - end loop; + Elmt := First_Elmt (Intra_Procs); + while Present (Elmt) loop + Ent := Node (Elmt); + Check_Internal_Call_Continue (N, Ent, Enclosing, Ent); + Next_Elmt (Elmt); + end loop; - In_Task_Activation := False; + In_Task_Activation := False; + end if; end Check_Task_Activation; ------------------------------- Index: sem_elab.ads =================================================================== --- sem_elab.ads (revision 251834) +++ sem_elab.ads (working copy) @@ -71,7 +71,7 @@ -- output a warning. -- For calls to a subprogram in a with'ed unit or a 'Access or variable - -- refernece (SPARK mode case), we require that a pragma Elaborate_All + -- reference (SPARK mode case), we require that a pragma Elaborate_All -- or pragma Elaborate be present, or that the referenced unit have a -- pragma Preelaborate, pragma Pure, or pragma Elaborate_Body. If none -- of these conditions is met, then a warning is generated that a pragma