[Ada] Creation of extra formals for primitive operations

Arnaud Charlet charlet@adacore.com
Tue Jul 7 13:19:00 GMT 2009


Extra formals used to convey accessibility information and constrained status
of an actual are created when a subprogram is frozen. This may be too late in
the rare case where a primitive operation of a type is called within the
initialization procedure for the type. This can only happen if the primitive
in question has an access controlling parameter that is the current instance of
the type. In such a case the extra formals must be created before the analysis
of the initialization procedure, to ensure that the analysis of the call adds
the proper accessibility value to the actuals. In general the subprogram will
be frozen after the call in the initialization procedure.

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

2009-07-07  Ed Schonberg  <schonberg@adacore.com>

	* exp_ch3.adb (Expand_Freeze_Record_Type): Add extra formals to
	primitive operations, in case one of them is called in the
	initialization procedure for the type.

-------------- next part --------------
Index: exp_ch3.adb
===================================================================
--- exp_ch3.adb	(revision 149318)
+++ exp_ch3.adb	(working copy)
@@ -53,6 +53,7 @@ with Sem_Aux;  use Sem_Aux;
 with Sem_Attr; use Sem_Attr;
 with Sem_Cat;  use Sem_Cat;
 with Sem_Ch3;  use Sem_Ch3;
+with Sem_Ch6;  use Sem_Ch6;
 with Sem_Ch8;  use Sem_Ch8;
 with Sem_Disp; use Sem_Disp;
 with Sem_Eval; use Sem_Eval;
@@ -6012,6 +6013,29 @@ package body Exp_Ch3 is
          if Present (Wrapper_Body_List) then
             Append_Freeze_Actions (Def_Id, Wrapper_Body_List);
          end if;
+
+         --  Create extra actuals for the primitive operations of the type.
+         --  This must be done before analyzing the body of the initialization
+         --  procedure, because a self-referential type might call one of these
+         --  primitives in the body of the init_proc itself.
+
+         declare
+            Elmt : Elmt_Id;
+            Subp : Entity_Id;
+
+         begin
+            Elmt := First_Elmt (Primitive_Operations (Def_Id));
+            while Present (Elmt) loop
+               Subp := Node (Elmt);
+               if not Has_Foreign_Convention (Subp)
+                 and then not Is_Predefined_Dispatching_Operation (Subp)
+               then
+                  Create_Extra_Formals (Subp);
+               end if;
+
+               Next_Elmt (Elmt);
+            end loop;
+         end;
       end if;
    end Expand_Freeze_Record_Type;
 


More information about the Gcc-patches mailing list