Patchwork [Ada] Ada 2012: AI05-0296, formal incomplete types.

login
register
mail settings
Submitter Arnaud Charlet
Date June 12, 2012, 10:34 a.m.
Message ID <20120612103446.GA23351@adacore.com>
Download mbox | patch
Permalink /patch/164377/
State New
Headers show

Comments

Arnaud Charlet - June 12, 2012, 10:34 a.m.
This patch implements AI05-0296, concerning freeze rules in the presence of
formal incomplete types: a formal abstract subprogram cannot have an incomplete
controlling type, and the profile of the actual subprogram is not frozen if it
includes a incomplete untagged type.

Compiling abstr.ads in Ada 2012 mode must yield:

---
   abstr.ads:4:07: controlling type of abstract formal subprogram cannot be
   incomplete type
   abstr.ads:19:03: type "T2" must be frozen before this point
   abstr.ads:19:03: instantiation abandoned
   abstr.ads:32:03: warning: no more representation items for type "Arr" defined
   at line 31
   abstr.ads:34:03: representation item appears too late
---
package Abstr is
   generic
      type T is tagged;
      with procedure Move (Obj : T) is abstract;   --  ERROR
   package Gen is
   private
   end;

   type T2 is tagged;

   generic
      with procedure Move (Obj : T2) ;
   package Gen2 is
   private
   end;

  procedure Shift (Obj : T2);

  package Inst is new Gen2 (Shift);  --  ERROR

  type T2 is tagged record
     Val : integer := 0;
  end record;

  generic
     type T is private;
  package Gen3 is
  private
  end;

  type Arr is array (1..10) of Boolean;
  package Inst2 is new Gen3 (Arr);

  pragma Pack (Arr);  --  ERROR, too late
end Abstr;

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

2012-06-12  Ed Schonberg  <schonberg@adacore.com>

	* sem_ch3.adb (Analyze_Subtype_Declaration): if an incomplete
	type is tagged, so is a subtype of it.
	* sem_ch12.adb (Validate_Actual_Subprogram): implement AI05-0296,
	concerning freeze rules in the presence of formal incomplete
	types: a formal abstract subprogram cannot have an incomplete
	controlling type, and the profile of the actual subprogram does
	not freeze if it includes an incomplete untagged type.

Patch

Index: sem_ch12.adb
===================================================================
--- sem_ch12.adb	(revision 188441)
+++ sem_ch12.adb	(working copy)
@@ -2664,6 +2664,14 @@ 
                Error_Msg_N
                  ("abstract formal subprogram must have a controlling type",
                   N);
+
+            elsif Ada_Version >= Ada_2012
+              and then Is_Incomplete_Type (Ctrl_Type)
+            then
+               Error_Msg_NE
+                 ("controlling type of abstract formal subprogram cannot " &
+                     "be incomplete type", N, Ctrl_Type);
+
             else
                Check_Controlling_Formals (Ctrl_Type, Nam);
             end if;
@@ -9411,6 +9419,59 @@ 
          end;
       end if;
 
+      --  In Ada 2012, enforce the (RM 13.14(10.2/3)) freezing rule concerning
+      --  formal incomplete types: a callable entity freezes its profile,
+      --  unless it has an incomplete untagged formal.
+
+      if Ada_Version >= Ada_2012 then
+         declare
+            F : Entity_Id;
+            Has_Untagged_Inc : Boolean;
+
+         begin
+            F := First_Formal (Analyzed_S);
+            Has_Untagged_Inc := False;
+            while Present (F) loop
+               if Ekind (Etype (F)) = E_Incomplete_Type
+                 and then not Is_Tagged_Type (Etype (F))
+               then
+                  Has_Untagged_Inc := True;
+                  exit;
+               end if;
+
+               F := Next_Formal (F);
+            end loop;
+
+            if Ekind (Analyzed_S) = E_Function
+              and then Ekind (Etype (Analyzed_S)) = E_Incomplete_Type
+              and then not Is_Tagged_Type (Etype (F))
+            then
+               Has_Untagged_Inc := True;
+            end if;
+
+            if Is_Entity_Name (Actual)
+              and then not Has_Untagged_Inc
+            then
+               F := First_Formal (Entity (Actual));
+               while Present (F) loop
+                  Freeze_Before (Instantiation_Node, Etype (F));
+
+                  if Is_Incomplete_Or_Private_Type (Etype (F))
+                    and then No (Full_View (Etype (F)))
+                    and then not Is_Generic_Type (Etype (F))
+                  then
+                     Error_Msg_NE
+                       ("type& must be frozen before this point",
+                          Instantiation_Node, Etype (F));
+                     Abandon_Instantiation (Instantiation_Node);
+                  end if;
+
+                  F := Next_Formal (F);
+               end loop;
+            end if;
+         end;
+      end if;
+
       return Decl_Node;
    end Instantiate_Formal_Subprogram;
 
Index: sem_ch3.adb
===================================================================
--- sem_ch3.adb	(revision 188428)
+++ sem_ch3.adb	(working copy)
@@ -4340,12 +4340,16 @@ 
 
             when E_Incomplete_Type =>
                if Ada_Version >= Ada_2005 then
-                  Set_Ekind (Id, E_Incomplete_Subtype);
 
-                  --  Ada 2005 (AI-412): Decorate an incomplete subtype
-                  --  of an incomplete type visible through a limited
-                  --  with clause.
+                  --  A subtype of an incomplete type can be explicitly tagged
 
+                  Set_Ekind              (Id, E_Incomplete_Subtype);
+                  Set_Is_Tagged_Type     (Id, Is_Tagged_Type (T));
+                  Set_Private_Dependents (Id, New_Elmt_List);
+
+                  --  Ada 2005 (AI-412): Decorate an incomplete subtype of an
+                  --  incomplete type visible through a limited with clause.
+
                   if From_With_Type (T)
                     and then Present (Non_Limited_View (T))
                   then