[Ada] Null procedures as actuals in instances

Submitted by Arnaud Charlet on Oct. 12, 2010, 9:38 a.m.


Message ID 20101012093826.GA6703@adacore.com
State New
Headers show

Commit Message

Arnaud Charlet Oct. 12, 2010, 9:38 a.m.
To accomodate possible preconditions on null procedures we create a null body
for them, and place it in the code at the point the subprogram is frozen. If
the subprogram is used as an actual in an instantiation of a child unit, the
visibility may be different between the point of definition and the freeze
point. Therefore the types that appear in the signature of the generated body
must be analyzed at the point of the declaration.

Test_Server below must compile quietly in Ada2005 mode

with Test_Services;
with Services.Context_Server;
package body Test_Server is
  type No_Context is null record;
  procedure Initialize (The_Context : in out No_Context) is null;

  package This_Server is new
        Test_Services.Context_Server (No_Context, Initialize);

  procedure Finalize (The_Context : access No_Context) is null;

  procedure Start (Name : in String) is
     This_Server.Start (Name);
  end Start;
end Test_Server;
package Test_Server is
  procedure Start (Name : in String);
end Test_Server;
   type Context is limited private;
   with procedure Initialize (The_Context : in out Context);
package Services.Context_Server is
   procedure Start (Name : in String);
end Services.Context_Server;
package body Services.Context_Server is
  Local_Context : Context;
  procedure Start (Name : in String) is
     Initialize (Local_Context);
  end Start;
end Services.Context_Server;
   type Kind is private;
package Services is
   procedure Do_Something (With_Kind : in Kind);
end Services;
package body Services is
   Local_Kind : Kind;

   procedure Do_Something (With_Kind : in Kind) is
      Local_Kind := With_Kind;
   end Do_Something;
end Services;
with Services;
package test_services is new services (boolean);

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

2010-10-12  Ed Schonberg  <schonberg@adacore.com>

	* sem_ch6.adb (Analyze_Subprogram_Declaration): If this is a
	declaration of a null procedure resolve the types of the profile of the
	generated null body now.

Patch hide | download patch | download mbox

Index: sem_ch6.adb
--- sem_ch6.adb	(revision 165316)
+++ sem_ch6.adb	(working copy)
@@ -2737,6 +2737,27 @@  package body Sem_Ch6 is
             Set_Defining_Identifier (Form,
               Make_Defining_Identifier (Loc,
                 Chars (Defining_Identifier (Form))));
+            --  Resolve the types of the formals now, because the freeze point
+            --  may appear in a different context, e.g. an instantiation.
+            if Nkind (Parameter_Type (Form)) /= N_Access_Definition then
+               Find_Type (Parameter_Type (Form));
+            elsif
+              No (Access_To_Subprogram_Definition (Parameter_Type (Form)))
+            then
+               Find_Type (Subtype_Mark (Parameter_Type (Form)));
+            else
+               --  the case of a null procedure with a formal that is an
+               --  access_to_subprogram type, and that is used as an actual
+               --  in an instantiation is left to the enthusiastic reader.
+               null;
+            end if;
             Next (Form);
          end loop;