Patchwork [Ada] Deriving from formal limited types

login
register
mail settings
Submitter Arnaud Charlet
Date Oct. 8, 2010, 10:17 a.m.
Message ID <20101008101717.GA10294@adacore.com>
Download mbox | patch
Permalink /patch/67158/
State New
Headers show

Comments

Arnaud Charlet - Oct. 8, 2010, 10:17 a.m.
In general it is illegal for a type derived from a formal limited type to be
non-limited.  AI05-096 makes an exception to this rule: the derivation is legal
if it appears in the private part of the generic, and the formal type is not
tagged. If the type is tagged, the legality check must be applied to the
private part of the package.

The following must compile quietly:

procedure Inst is
   generic
       type Lim is limited private;
   package Gen is
   private
       type New_Lim is limited new Lim;
   end Gen;

   package New_Gen is new Gen (Integer);
begin
   null;
end;

The following must be rejected with the message:

   inst2.adb:9:04: instantiation error at line 6
   inst2.adb:9:04: parent type "Lim" of limited type must be limited

---
procedure Inst2 is
   generic
       type Lim is tagged limited private;
   package Gen is
   private
       type New_Lim is limited new Lim with null record;
   end Gen;
   type Rec is tagged null record;
   package New_Gen is new Gen (Rec);
begin
   null;
end;

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

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

	* sem_ch3.adb (Derived_Type_Declaration): In the private part of an
	instance, it is legal to derive from a non-limited actual when the
	formal type is untagged limited.
	* sem_ch12.adb (Instantiate_Type): For a formal private type, use
	analyzed formal as Generic_Parent_Type, to simplify later checks.

Patch

Index: sem_ch3.adb
===================================================================
--- sem_ch3.adb	(revision 165155)
+++ sem_ch3.adb	(working copy)
@@ -13738,9 +13738,24 @@  package body Sem_Ch3 is
              (not Is_Interface (Parent_Type)
                or else not Is_Limited_Interface (Parent_Type))
          then
-            Error_Msg_NE
-              ("parent type& of limited type must be limited",
-               N, Parent_Type);
+
+            --  AI05-0096 : a derivation in the private part of an instance is
+            --  legal if the generic formal is untagged limited, and the actual
+            --  is non-limited.
+
+            if Is_Generic_Actual_Type (Parent_Type)
+              and then In_Private_Part (Current_Scope)
+              and then
+                not Is_Tagged_Type
+                  (Generic_Parent_Type (Parent (Parent_Type)))
+            then
+               null;
+
+            else
+               Error_Msg_NE
+                 ("parent type& of limited type must be limited",
+                  N, Parent_Type);
+            end if;
          end if;
       end if;
    end Derived_Type_Declaration;
Index: sem_ch12.adb
===================================================================
--- sem_ch12.adb	(revision 165152)
+++ sem_ch12.adb	(working copy)
@@ -10355,6 +10355,10 @@  package body Sem_Ch12 is
       --  parent, but the analyzed formal that includes the interface
       --  operations of all its progenitors.
 
+      --  Same treatment for formal private types, so we can check whether the
+      --  type is tagged limited when validating derivations in the private
+      --  part. (See AI05-096).
+
       if Nkind (Def) = N_Formal_Derived_Type_Definition then
          if Present (Interface_List (Def)) then
             Set_Generic_Parent_Type (Decl_Node, A_Gen_T);
@@ -10363,7 +10367,7 @@  package body Sem_Ch12 is
          end if;
 
       elsif Nkind (Def) = N_Formal_Private_Type_Definition then
-         Set_Generic_Parent_Type (Decl_Node, Ancestor);
+         Set_Generic_Parent_Type (Decl_Node, A_Gen_T);
       end if;
 
       --  If the actual is a synchronized type that implements an interface,