CVS difference for ais/ai-00251.txt

Differences between 1.19 and version 1.20
Log of other versions for file ais/ai-00251.txt

--- ais/ai-00251.txt	2004/01/23 04:45:15	1.19
+++ ais/ai-00251.txt	2004/04/06 19:57:01	1.20
@@ -1,6 +1,32 @@
-!standard 03.04    (02)                            04-01-22  AI95-00251/11
-!standard 03.09.01 (02)
+!standard 03.04    (02)                            04-03-29  AI95-00251/12
+!standard 02.09    (03)
+!standard 03.02.01 (02)
+!standard 03.04    (03)
+!standard 03.04    (08)
+!standard 03.04    (23)
+!standard 03.04    (35)
+!standard 03.04.01 (02)
+!standard 03.04.01 (10)
+!standard 03.09.03 (04)
+!standard 03.09.03 (05)
+!standard 03.09.04 (01)
+!standard 04.05.02 (03)
+!standard 04.06 (08-10)
+!standard 04.06 (11/1)
+!standard 04.06 (12/1)
+!standard 04.06 (12.1/1)
+!standard 04.06 (13-24)
+!standard 07.03 (02)
+!standard 08.03 (12)
+!standard 08.03 (26/1)
+!standard 12.05 (03)
+!standard 12.05.01 (03)
+!standard 12.05.01 (15)
+!standard 12.05.05 (01)
+!standard 13.14 (07)
 !class amendment 00-12-04
+!status Amendment 200Y 04-03-29
+!status ARG Approved 7-0-1  04-03-07
 !status work item 00-12-04
 !status received 00-12-04
 !priority High
@@ -16,6 +42,10 @@
 interface type dispatch to code bodies associated with specific tagged types
 that are derived from the interface.
 
+This proposal also clarifies that it is always legal to convert between two
+types if they have a common ancestor and they meet the restrictions of
+4.6(22-23).
+
 !problem
 
 A number of recent language designs have adopted a compromise between full
@@ -124,9 +154,9 @@
     Each class of types that includes the parent type or an interface ancestor
     type also includes the derived type.
 
-Add after paragraph 25:
+Add after paragraph 23:
 
-    If a type declaration names an interface type in an interface list, then
+    If a type declaration names an interface type in an interface_list, then
     the declared type inherits any user-defined primitive subprograms of the
     interface type in the same way.
 
@@ -140,14 +170,14 @@
 
 Insert after the first sentence of paragraph 2:
 
-     A derived type or interface type is also derived from each of its
-     interface ancestor types, if any.
+    A derived type or interface type is also derived from each of its
+    interface ancestor types, if any.
 
 Replace the last sentence of paragraph 10 with:
 
     An *ultimate ancestor* of a type is an ancestor of that type that
-    is not a descendant of any other type and that is not an interface
-    type (see 3.9.4). Each untagged type has a unique ultimate ancestor.
+    is not a descendant of any other type. Each untagged type has a
+    unique ultimate ancestor.
 
 
 3.9.3 Abstract Types and Subprograms
@@ -188,7 +218,7 @@
         The type of a subtype named in an interface_list shall be an
         interface type.
 
-        If a type declaration names an interface type in an interface list,
+        If a type declaration names an interface type in an interface_list,
         then the accessibility level of the declared type shall not be
         statically deeper than that of the interface type; also, the declared
         type shall not be declared in a generic body if the interface type is
@@ -197,10 +227,70 @@
         A descendant of an interface type shall be limited if and only
         if the interface type is limited.
 
+	AARM Note:
+	Reason: Without this rule, an implementation would no longer know
+	statically whether a dispatching function call is a call to a function
+	with a return-by-reference result. This could be implemented, but it
+	is a substantial and unnecessary complication. The complications of
+	AI-318 occur precisely because we're trying to avoid runtime choices
+	between normal and return-by-reference functions. Besides, the language
+	has, as a matter of general principle, steered away from constructs
+	which would allow a limited view of an object of a non-limited tagged
+	type. We may want to reconsider this if some form of AI-318 is included
+	in the standard. End AARM Note.
+
         A full view shall be a descendant of an interface type if and only if
         the  corresponding partial view (if any) is also a descendant of the
         interface type.
 
+
+	AARM Note:
+	Reason: If this example,
+
+            package P is
+              packge Pkg is
+                  type Ifc is interface;
+                  procedure Foo (X : Ifc) is abstract;
+              end;
+
+              type Parent_1 is tagged null record;
+
+              type T1 is new Parent_1 with private;
+            private
+              type Parent_2 is new Parent_1 and Pkg.Ifc with null record;
+              procedure Foo (X : Parent_2); -- Foo #1
+
+              type T1 is new Parent_2 with null record;
+            end;
+
+            with P;
+            package P_Client is
+              type T2 is new P.T1 and P.Pkg.Ifc with null record;
+              procedure Foo (X : T2); -- Foo #2
+              X : T2;
+            end P2_Client;
+
+            with P_Client;
+            package body P is
+              ...
+            begin
+              Pkg.Foo (Pkg.Ifc'Class (P_Client.X));
+                 -- call Foo #2
+              Pkg.Foo (Pkg.Ifc'Class (T1 (P_Client.X)));
+                 -- call Foo #1
+            end P2;
+
+	, were legal (it is illegal because the completion of T1 is descended
+        an interface that the partial view is not descended from), then
+        we would have two dispatching calls to Pkg.Foo with the
+        two controlling operands having the same tag and yet different
+        bodies would be executed. The two conversions to Pkg.Ifc'Class
+        would map Pkg.Foo to different slots in the same dispatch table
+        because the source types of the conversions are different.
+
+        This would be bad.
+	End AARM Note
+
         For an interface type declared in a visible part, a primitive
         subprogram shall not be declared in the private part.
 
@@ -219,11 +309,17 @@
         type for the simple_expression is the tested type.
 
 4.6 Type Conversions
+
+    Insert the following before paragraph 8:
 
-    Replace paragraphs 21-23 with
+        In a view conversion for an untagged type, the target type shall be
+        convertible (back) to the operand type.
 
-        If the target type is tagged then either:
+        If there is a type that is an ancestor of both the target type
+        and the operand type, then
 
+            - The target type shall be untagged; or
+
             - The operand type shall be covered by or descended from the target
               type; or
 
@@ -233,22 +329,16 @@
             - The operand and target types shall both be class-wide types and
               the specific type associated with at least one of them shall
               be an interface type.
+
+        If there is no type that is an ancestor of both the target type
+        and the operand type, then
 
-        If the target type is not included in any of the above five cases,
-        there shall be a type that is an ancestor of both the target type
-        and the operand type.
-
-6.1  Subprogram Declarations
-
-Replace
-   subprogram_specification ::= PROCEDURE defining_program_unit_name
-                                          parameter_profile
-with
-   procedure_specification ::= PROCEDURE defining_program_unit_name
-                                         parameter_profile
-   subprogram_specification ::= procedure_specification
+    Existing paragraphs 8, 9-12.1/1, 13-17, and 18-20 become bullets under
+    "If there is no type ...".
 
+    Delete the paragraphs 21-24 (they're included above).
 
+
 7.3 Private Types and Private Extensions
 
     Replace
@@ -292,6 +382,31 @@
           homograph remains that is not thus overridden, then one is chosen
           arbitrarily to override the others.
 
+
+	AARM Note: Discussion: It is intended that in the case where the
+	 implementation arbitrarily chooses one overrider from among a group
+	 of inherited subprograms, users should be unable to determine which
+	 member was chosen. This rule is needed in order to allow
+
+	      package Outer is
+	        package P1 is
+	           type Ifc1 is interface;
+	           procedure Null_Procedure (X : Ifc1) is null;
+	           procedure Abstract_Subp  (X : Ifc1) is abstract;
+	         end P1;
+
+	         package P2  is
+	           type Ifc2  is interface;
+	           procedure Null_Procedure (X : Ifc2) is null;
+	           procedure Abstract_Subp  (X : Ifc2) is abstract;
+	         end P2;
+
+	         type T is new P1.Ifc1 and P2.Ifc2 with null record;
+	      end Outer;
+
+	    without requiring that T explicitly override any of its inherited
+	    operations.
+
       * For an implicit declaration of a primitive subprogram in a generic unit,
         there is a copy of this declaration in an instance. However, a whole new
         set of primitive subprograms is implicitly declared for each type
@@ -337,7 +452,7 @@
 
 
 
-12.5.1 Formal Private Types
+12.5.1 Formal Private and Derived Types
 
     Replace
         formal_derived_type_definition ::= [ABSTRACT] NEW subtype_mark
@@ -369,6 +484,10 @@
 
         The actual type shall be an interface type.
 
+	AARM Note: Reason: The class of all interface types includes
+        non-interface descendants of interface types. Such types must
+	not match a formal interface. End AARM Note.
+
         The actual type shall be a descendant of every ancestor of
         the formal type.
 
@@ -523,64 +642,14 @@
         type D is new I.T; -- formerly legal, now illegal.
 
    Disallowing this case does not seem like a bad thing, but it is a change.
-
-
-3) Yes, it really is illegal if the parent type of a private extension's
-   completion happens to be descended from some interface that the
-   private view was not descended from. This may turn out to be a pain.
-
-   This rule is, unfortunately, necessary. If this example,
-
-        package P is
-          packge Pkg is
-              type Ifc is interface;
-              procedure Foo (X : Ifc) is abstract;
-          end;
-
-          type Parent_1 is tagged null record;
-
-          type T1 is new Parent_1 with private;
-        private
-          type Parent_2 is new Parent_1 and Pkg.Ifc with null record;
-          procedure Foo (X : Parent_2); -- Foo #1
-
-          type T1 is new Parent_2 with null record;
-        end;
-
-        with P;
-        package P_Client is
-          type T2 is new P.T1 and P.Pkg.Ifc with null record;
-          procedure Foo (X : T2); -- Foo #2
-          X : T2;
-        end P2_Client;
-
-        with P_Client;
-        package body P is
-          ...
-        begin
-          Pkg.Foo (Pkg.Ifc'Class (P_Client.X));
-             -- call Foo #2
-          Pkg.Foo (Pkg.Ifc'Class (T1 (P_Client.X)));
-             -- call Foo #1
-        end P2;
-
-   , were legal (it is illegal because the completion of T1 is descended
-   an interface that the partial view is not descended from), then
-   we would have two dispatching calls to Pkg.Foo with the
-   two controlling operands having the same tag and yet different
-   bodies would be executed. The two conversions to Pkg.Ifc'Class
-   would map Pkg.Foo to different slots in the same dispatch table
-   because the source types of the conversions are different.
-
-   We want to prevent this sort of thing.
 
-4) A type derived from an interface type should inherit the same subprograms
+3) A type derived from an interface type should inherit the same subprograms
    as a type which is derived from both the interface type and an ancestor of
    the interface type. The two type definitions should be indistinguishable,
    in the sense that adding or deleting the explicit redundant derivation
    relationship should be a semantics-preserving transformation.
 
-5) It is intended that there should be no real difference between the two
+4) It is intended that there should be no real difference between the two
    forms of derivation from interface types. For example, replacing
    the declaration
        type T is new Interface_Type_1 and Interface_Type_2 with null record;
@@ -588,7 +657,7 @@
        type T is new Interface_Type_2 and Interface_Type_1 with null record;
    should be semantics-preserving.
 
-6) Someone asked why an interface type declared in a visible part is not
+5) Someone asked why an interface type declared in a visible part is not
    allowed to have primitive operations declared in the private part.
    A dispatching call to a primitive of an interface type will execute
    the body of a corresponding routine associated with the specific type
@@ -598,55 +667,60 @@
    declared in the private part "is overriding an abstract subprogram
    implicitly declared in the visible part", but this doesn't seem to be
    worth the bother because this could only be used to override an abstract
-   procedure with a null procedure. There does not appear to be universal
-   agreement on this point.
+   procedure with a null procedure.
+
+
+The changes to section 4.6 also include a solution for the problem originally
+identified in AI-219 (which is now folded into this AI).
+
+Originally, 4.6(21) included the following:
+    "If the target type is not included in any of the above 4 cases, then ..."
+
+Thus, 4.6(21-23) only applied if the target type was not a numeric type,
+an array type, a general access type, or an access-to-subprogram type.
+
+This turned out to be a mistake.
+
+It might seem at first that this restriction would have no consequences -
+if the two types are known to have a common ancestor, then surely the
+characteristics mentioned in 4.6(8-20) would all match up and the
+conversion would be legal.
+
+This is not always true.
+
+Consider the following example:
+
+     package P is
+         type Target is private;
+     private
+         type Target is range 1 .. 10;
+         ... ;
+     end P;
 
-7) Someone asked why a limited interface cannot be implemented by a
-   non-limited type. An implementation would no longer know statically
-   whether a dispatching function call is a call to a function with a
-   return-by-reference result. This could be implemented, but it seems
-   like an unnecessary complication. The language has, as a matter of
-   general principle, steered away from constructs which would allow a
-   limited view of an object of a non-limited tagged type.
-
-8) It is intended that in the case where the implementation
-   arbitrarily chooses one overrider from among a group of inherited
-   subprograms, users should be unable to determine which
-   member was chosen. The "one is chosen arbitrarily to override the others"
-   monkey business in 8.3 is needed in order to allow
-
-      package Outer is
-        package P1 is
-           type Ifc1 is interface;
-           procedure Null_Procedure (X : Ifc1) is null;
-           procedure Abstract_Subp  (X : Ifc1) is abstract;
-         end P1;
-
-         package P2  is
-           type Ifc2  is interface;
-           procedure Null_Procedure (X : Ifc2) is null;
-           procedure Abstract_Subp  (X : Ifc2) is abstract;
-         end P2;
-
-         type T is new P1.Ifc1 and P2.Ifc2 with null record;
-      end Outer;
-
-    without requiring that T explicitly override any of its inherited
-    operations. If requiring explicit overrides in this case is considered
-    to be ok, then that bit of oddness could be deleted from 8.3.
-
-    If it turns out that users can somehow determine which
-    member was chosen and that this approach introduces serious portability
-    problems, then one could impose an arbitrary-but-determininistic
-    tie-breaking scheme (e.g. make use of the order of the interface types,
-    prefering operators inherited from "earlier" types; in the above
-    example, this would mean that the operators inherited from P1.Ifc1
-    would override those inherited from P2.Ifc2).
-
-9) The class of all interface types includes non-interface descendants
-   of interface types. This is the reason for the 12.5.5 legality rule
-   "The actual type shall be an interface type".
+     with P;
+     package Q is
+         type Source is new P.Target;
+         function Source_Value return Source;
+     end Q;
 
+     with Q
+     package body P is
+         Converted : Target := Target (Q.Source_Value); -- legal
+         ...
+     end P;
+
+As seen from the point of the type conversion, Target is a numeric type
+although Source is not. With the original wording, 4.6(21-23) does not
+apply and the conversion is would be illegal.
+
+Thus, the Standard as as written is incompatible with Ada 83, which
+allowed conversions between any two type related by derivation. Certainly
+no such incompatibility was intended; no such incompatibility is listed
+under the "Incompatibilities with Ada 83" heading in the AARM.
+
+This AI's reorganization of 4.6 addresses this problem.
+
+
 !example
 
 An example involving interface types:
@@ -773,11 +847,631 @@
          Object_Monitoring.Register (X'access);
       end;
 
+!corrigendum 2.9(3)
+
+@drepl
+NOTES@hr
+6 The reserved words appear in @b<lower case boldface> in this International
+Standard, except when used in the @fa<designator> of an attribute (see
+4.1.4). Lower case boldface is also used for a reserved word
+in a @fa<string_literal> used as an @fa<operator_symbol>. This is merely a
+convention @emdash programs may be written in whatever typeface is desired and
+available.
+@dby
+@b<interface> is a nonreserved keyword.
+
+NOTES@hr
+6 The reserved words appear in @b<lower case boldface> in this International
+Standard, except when used in the @fa<designator> of an attribute (see
+4.1.4). Lower case boldface is also used for a reserved word
+in a @fa<string_literal> used as an @fa<operator_symbol>. This is merely a
+convention @emdash programs may be written in whatever typeface is desired and
+available.
+
+!corrigendum 3.2.1(4)
+
+@drepl
+@xcode<@fa<type_definition ::=
+     enumeration_type_definition | integer_type_definition
+   | real_type_definition | array_type_definition
+   | record_type_definition | access_type_definition
+   | derived_type_definition>>
+@dby
+@xcode<@fa<type_definition ::=
+     enumeration_type_definition | integer_type_definition
+   | real_type_definition | array_type_definition
+   | record_type_definition | access_type_definition
+   | derived_type_definition | interface_type_definition>>
+
+!corrigendum 3.4(2)
+
+@drepl
+@xcode<@fa<derived_type_definition ::= [>@ft<@b<abstract>>@fa<] >@ft<@b<new> @i<parent_>>@fa<subtype_indication [record_extension_part]>>
+@dby
+@xcode<@fa<interface_list ::= interface_subtype_mark {>@ft<@b<and>>@fa< interface_subtype_mark}>>
+
+@xcode<@fa<derived_type_definition ::=
+    [>@ft<@b<abstract>>@fa<] >@ft<@b<new> @i<parent_>>@fa<subtype_indication [[>@ft<@b<and>>@fa< interface_list] record_extension_part]>>
+
+!corrigendum 3.4(3)
+
+@drepl
+The @i<parent_>@fa<subtype_indication> defines the parent subtype; its type is
+the parent type.
+@dby
+The @i<parent_>@fa<subtype_indication> defines the parent subtype; its type is
+the parent type. A derived type has one parent type and zero or more interface
+ancestor types.
+
+!corrigendum 3.4(8)
+
+@drepl
+@xbullet<Each class of types that includes the parent type also includes the
+derived type.>
+@dby
+@xbullet<Each class of types that includes the parent type or an interface
+ancestor type also includes the derived type.>
+
+!corrigendum 3.4(23)
+
+@dinsa
+If a primitive subprogram of the parent type is visible at the place of the
+@fa<derived_type_definition>, then the corresponding inherited subprogram is
+implicitly declared immediately after the @fa<derived_type_definition>.
+Otherwise, the inherited subprogram is implicitly declared later or not at all,
+as explained in 7.3.1.
+@dinst
+If a type declaration names an interface type in an @fa<interface_list>, then
+the declared type inherits any user-defined primitive subprograms of the
+interface type in the same way.
+
+!corrigendum 3.4(35)
+
+@dinsa
+17  If the reserved word @b<abstract> is given in the declaration of a type,
+the type is abstract (see 3.9.3).
+@dinst
+18  An interface type which has an interface ancestor "is derived from"
+that type, and therefore is a derived type. A @fa<derived_type_definition>,
+however, never defines an interface type.
+
+!corrigendum 3.4.1(02)
+
+@drepl
+A derived type is @i<derived from> its parent type @i<directly>; it is derived
+@i<indirectly> from any type from which its parent type is derived. The
+derivation class of types for a type @i<T> (also called the class @i<rooted>
+at @i<T>) is the set consisting of @i<T> (the @i<root type> of the class) and
+all types derived from @i<T> (directly or indirectly) plus any associated
+universal or class-wide types (defined below).
+@dby
+A derived type is @i<derived from> its parent type @i<directly>; it is derived
+@i<indirectly> from any type from which its parent type is derived. A derived
+type or interface type is also derived from each of its interface ancestor
+types, if any. The derivation class of types for a type @i<T> (also called the
+class @i<rooted> at @i<T>) is the set consisting of @i<T> (the @i<root type> of
+the class) and all types derived from @i<T> (directly or indirectly) plus any
+associated universal or class-wide types (defined below).
+
+!corrigendum 3.4.1(10)
+
+@drepl
+A specific type @i<T2> is defined to be a @i<descendant> of a type @i<T1> if
+@i<T2> is the same as @i<T1>, or if @i<T2> is derived (directly or indirectly)
+from @i<T1>. A class-wide type @i<T2>'Class is defined to be a descendant of
+type @i<T1> if @i<T2> is a descendant of @i<T1>. Similarly, the universal types
+are defined to be descendants of the root types of their classes. If a type
+@i<T2> is a descendant of a type @i<T1>, then @i<T1> is called an @i<ancestor>
+of @i<T2>. The @i<ultimate ancestor> of a type is the ancestor of the type that
+is not a descendant of any other type.
+@dby
+A specific type @i<T2> is defined to be a @i<descendant> of a type @i<T1> if
+@i<T2> is the same as @i<T1>, or if @i<T2> is derived (directly or indirectly)
+from @i<T1>. A class-wide type @i<T2>'Class is defined to be a descendant of
+type @i<T1> if @i<T2> is a descendant of @i<T1>. Similarly, the universal types
+are defined to be descendants of the root types of their classes. If a type
+@i<T2> is a descendant of a type @i<T1>, then @i<T1> is called an @i<ancestor>
+of @i<T2>. The @i<ultimate ancestor> of a type is an ancestor of that type that
+is not a descendant of any other type. Each untagged type has a unique
+ultimate ancestor.
+
+!corrigendum 3.9.3(04)
+
+@drepl
+For a derived type, if the parent or ancestor type has an abstract primitive
+subprogram, or a primitive function with a controlling result, then:
+@dby
+If a type inherits a subprogram corresponding to an abstract subprogram or to a
+function with a controlling result, then
+
+!corrigendum 3.9.3(05)
+
+@drepl
+@xbullet<If the derived type is abstract or untagged, the inherited subprogram
+is abstract.>
+@dby
+@xbullet<If the inheriting type is abstract or untagged, the inherited
+subprogram is abstract.>
+
+!corrigendum 3.9.4(1)
+
+@dinsc
+An interface type is an abstract tagged type intended for use
+in providing a restricted form of multiple inheritance.
+A tagged type may be derived from multiple interface types.
+
+@i<@s8<Syntax>>
+
+@xcode<@fa<interface_type_definition ::= [>@ft<@b<limited>>@fa<] >@ft<@b<interface>>@fa< [interface_list]>>
+
+@i<@s8<Static Semantics>>
+
+An interface type (also called an "interface") is a specific abstract
+tagged type that is defined by an @fa<interface_type_definition>.
+
+@i<@s8<Legality Rules>>
+
+An interface type shall have no components.
+
+All user-defined primitive subprograms of an interface type shall be
+abstract subprograms or null procedures.
+
+The type of a subtype named in an @fa<interface_list> shall be an
+interface type.
+
+If a type declaration names an interface type in an @fa<interface_list>,
+then the accessibility level of the declared type shall not be
+statically deeper than that of the interface type; also, the declared
+type shall not be declared in a generic body if the interface type is
+declared outside that body.
+
+A descendant of an interface type shall be limited if and only
+if the interface type is limited.
+
+A full view shall be a descendant of an interface type if and only if
+the  corresponding partial view (if any) is also a descendant of the
+interface type.
+
+For an interface type declared in a visible part, a primitive
+subprogram shall not be declared in the private part.
+
+In addition to the places where Legality Rules normally apply
+(see 12.3), these rules apply also in the private part of an instance
+of a generic unit.
+
+!corrigendum 4.5.2(3)
+
+@drepl
+The @i<tested type> of a membership test is the type of the @fa<range> or the
+type determined by the @fa<subtype_mark>. If the tested type is tagged, then
+the @fa<simple_expression> shall resolve to be of a type that covers or is
+covered by the tested type; if untagged, the expected type for the
+@fa<simple_expression> is the tested type.
+@dby
+The @i<tested type> of a membership test is the type of the @fa<range> or the
+type determined by the @fa<subtype_mark>. If the tested type is tagged, then
+then the @fa<simple_expression> shall resolve to be of a type that is
+convertible (see 4.6) to the tested type; if untagged, the expected
+type for the @fa<simple_expression> is the tested type.
+
+!corrigendum 4.6(8)
+
+@drepl
+If the target type is a numeric type, then the operand type shall be a numeric
+type.
+@dby
+In a view conversion for an untagged type, the target type shall be convertible
+(back) to the operand type.
+
+If there is a type that is an ancestor of both the target type and the operand
+type, then
+
+@xbullet<The target type shall be untagged; or>
+
+@xbullet<The operand type shall be covered by or descended from the target
+type; or>
+
+@xbullet<The operand type shall be a class-wide type that covers the target
+type; or>
+
+@xbullet<The operand and target types shall both be class-wide types and the
+specific type associated with at least one of them shall be an interface type.>
+
+If there is no type that is an ancestor of both the target type
+and the operand type, then
+
+@xbullet<If the target type is a numeric type, then the operand type shall be a
+numeric type.>
+
+!corrigendum 4.6(9)
+
+@drepl
+If the target type is an array type, then the operand type shall be an array
+type. Further:
+@dby
+@xbullet<If the target type is an array type, then the operand type shall be an array
+type. Further:>
+
+!corrigendum 4.6(10)
+
+@drepl
+@xbullet<The types shall have the same dimensionality;>
+@dby
+@xinbull<The types shall have the same dimensionality;>
+
+!corrigendum 4.6(11/1)
+
+@drepl
+@xbullet<Corresponding index types shall be convertible;>
+@dby
+@xinbull<Corresponding index types shall be convertible;>
+
+!corrigendum 4.6(12/1)
+
+@drepl
+@xbullet<The component subtypes shall statically match; and>
+@dby
+@xinbull<The component subtypes shall statically match; and>
+
+!corrigendum 4.6(12.1/1)
+
+@drepl
+@xbullet<In a view conversion, the target type and the operand type shall both
+or neither have aliased components.>
+@dby
+@xinbull<In a view conversion, the target type and the operand type shall both
+or neither have aliased components.>
+
+!corrigendum 4.6(13)
+
+@drepl
+If the target type is a general access type, then the operand type shall be an
+access-to-object type. Further:
+@dby
+@xbullet<If the target type is a general access type, then the operand type
+shall be an access-to-object type. Further:>
+
+!corrigendum 4.6(14)
+
+@drepl
+@xbullet<If the target type is an access-to-variable type, then the operand
+type shall be an access-to-variable type;>
+@dby
+@xinbull<If the target type is an access-to-variable type, then the operand
+type shall be an access-to-variable type;>
+
+!corrigendum 4.6(15)
+
+@drepl
+@xbullet<If the target designated type is tagged, then the operand designated
+type shall be convertible to the target designated type;>
+@dby
+@xinbull<If the target designated type is tagged, then the operand designated
+type shall be convertible to the target designated type;>
+
+!corrigendum 4.6(16)
+
+@drepl
+@xbullet<If the target designated type is not tagged, then the designated types
+shall be the same, and either the designated subtypes shall statically match or
+the target designated subtype shall be discriminated and unconstrained; and>
+@dby
+@xinbull<If the target designated type is not tagged, then the designated types
+shall be the same, and either the designated subtypes shall statically match or
+the target designated subtype shall be discriminated and unconstrained; and>
+
+!corrigendum 4.6(17)
+
+@drepl
+@xbullet<The accessibility level of the operand type shall not be statically
+deeper than that of the target type. In addition to the places where Legality
+Rules normally apply (see 12.3), this rule applies also in the private part of
+an instance of a generic unit.>
+@dby
+@xinbull<The accessibility level of the operand type shall not be statically
+deeper than that of the target type. In addition to the places where Legality
+Rules normally apply (see 12.3), this rule applies also in the private part of
+an instance of a generic unit.>
+
+!corrigendum 4.6(18)
+
+@drepl
+If the target type is an access-to-subprogram type, then the operand
+type shall be an access-to-subprogram type. Further:
+@dby
+@xbullet<If the target type is an access-to-subprogram type, then the operand
+type shall be an access-to-subprogram type. Further:>
+
+!corrigendum 4.6(19)
+
+@drepl
+@xbullet<The designated profiles shall be subtype-conformant.>
+@dby
+@xinbull<The designated profiles shall be subtype-conformant.>
+
+!corrigendum 4.6(20)
+
+@drepl
+@xbullet<The accessibility level of the operand type shall not be statically
+deeper than that of the target type. In addition to the places where Legality
+Rules normally apply (see 12.3), this rule applies also in the private part of
+an instance of a generic unit. If the operand type is declared within a generic
+body, the target type shall be declared within the generic body.>
+@dby
+@xinbull<The accessibility level of the operand type shall not be statically
+deeper than that of the target type. In addition to the places where Legality
+Rules normally apply (see 12.3), this rule applies also in the private part of
+an instance of a generic unit. If the operand type is declared within a generic
+body, the target type shall be declared within the generic body.>
+
+!corrigendum 4.6(21)
+
+@ddel
+If the target type is not included in any of the above four cases, there shall
+be a type that is an ancestor of both the target type and the operand type.
+Further, if the target type is tagged, then either:
+
+!corrigendum 4.6(22)
+
+@ddel
+@xbullet<The operand type shall be covered by or descended from the target
+type; or>
+
+!corrigendum 4.6(23)
+
+@ddel
+@xbullet<The operand type shall be a class-wide type that covers the target
+type.>
+
+!corrigendum 4.6(24)
+
+@ddel
+In a view conversion for an untagged type, the target type shall be convertible
+(back) to the operand type.
+
+!corrigendum 7.3(02)
+
+@drepl
+@xcode<@fa<private_extension_declaration ::=
+   >@ft<@b<type>>@fa< defining_identifier [discriminant_part] >@ft<@b<is>>@fa<
+     [>@ft<@b<abstract>>@fa<] >@ft<@b<new>>@fa< ancestor_subtype_indication >@ft<@b<with private>>@fa<;>>
+@dby
+@xcode<@fa<private_extension_declaration ::=
+   >@ft<@b<type>>@fa< defining_identifier [discriminant_part] >@ft<@b<is>>@fa<
+     [>@ft<@b<abstract>>@fa<] >@ft<@b<new>>@fa< ancestor_subtype_indication [>@ft<@b<and>>@fa< interface_list] >@ft<@b<with private>>@fa<;>>
+
+!corrigendum 8.3(12)
+
+@dinsa
+@xbullet<An implicit declaration of an inherited subprogram overrides a
+previous implicit declaration of an inherited subprogram.>
+@dinss
+@xbullet<If two or more homographs are implicitly declared at the same place:>
+@xinbull<If one is a non-null non-abstract subprogram, then it overrides
+all which are null or abstract subprograms.>
+@xinbull<If all are null procedures or abstract subprograms, then any null
+procedure overrides all abstract subprograms; if more than one homograph
+remains that is not thus overridden, then one is chosen arbitrarily to override
+the others.>
+
+!corrigendum 8.3(26/1)
+
+@drepl
+A non-overridable declaration is illegal if there is a homograph occurring
+immediately within the same declarative region that is visible at the place of
+the declaration, and is not hidden from all visibility by the non-overridable
+declaration. In addition, a type extension is illegal if somewhere within its
+immediate scope it has two visible components with the same name. Similarly,
+the @fa<context_clause> for a @fa<subunit> is illegal if it mentions (in a
+@fa<with_clause>) some library unit, and there is a homograph of the library
+unit that is visible at the place of the corresponding stub, and the homograph
+and the mentioned library unit are both declared immediately within the same
+declarative region. These rules also apply to dispatching operations declared
+in the visible part of an instance of a generic unit. However, they do not
+apply to other overloadable declarations in an instance; such declarations may
+have type conformant profiles in the instance, so long as the corresponding
+declarations in the generic were not type conformant.
+@dby
+A non-overridable declaration is illegal if there is a homograph occurring
+immediately within the same declarative region that is visible at the place of
+the declaration, and is not hidden from all visibility by the non-overridable
+declaration. In addition, a type extension is illegal if somewhere within its
+immediate scope it has two visible components with the same name. Similarly,
+the @fa<context_clause> for a @fa<subunit> is illegal if it mentions (in a
+@fa<with_clause>) some library unit, and there is a homograph of the library
+unit that is visible at the place of the corresponding stub, and the homograph
+and the mentioned library unit are both declared immediately within the same
+declarative region.
+
+If two or more homographs are implicitly declared at the same place (and not
+overridden by a non-overridable declaration) then at most one shall be a
+non-null non-abstract subprogram. If all are null or abstract, then all of the
+null subprograms shall be fully conformant with one another. If all are
+abstract, then all of the subprograms shall be fully conformant with one
+another.
+
+All of these rules also apply to dispatching operations declared in the visible
+part of an instance of a generic unit. However, they do not apply to other
+overloadable declarations in an instance; such declarations may have type
+conformant profiles in the instance, so long as the corresponding declarations
+in the generic were not type conformant.
+
+!corrigendum 12.5(03)
+
+@drepl
+@xcode<@fa<formal_type_definition ::=
+      formal_private_type_definition
+    | formal_derived_type_definition
+    | formal_discrete_type_definition
+    | formal_signed_integer_type_definition
+    | formal_modular_type_definition
+    | formal_floating_point_definition
+    | formal_ordinary_fixed_point_definition
+    | formal_decimal_fixed_point_definition
+    | formal_array_type_definition
+    | formal_access_type_definition>>
+@dby
+@xcode<@fa<formal_type_definition ::=
+      formal_private_type_definition
+    | formal_derived_type_definition
+    | formal_discrete_type_definition
+    | formal_signed_integer_type_definition
+    | formal_modular_type_definition
+    | formal_floating_point_definition
+    | formal_ordinary_fixed_point_definition
+    | formal_decimal_fixed_point_definition
+    | formal_array_type_definition
+    | formal_access_type_definition
+    | formal_interface_type_definition>>
+
+!corrigendum 12.5.1(03)
+
+@drepl
+@xcode<@fa<formal_derived_type_definition ::= [>@ft<@b<abstract>>@fa<] >@ft<@b<new>>@fa< subtype_mark [>@ft<@b<with private>>@fa<]>>
+@dby
+@xcode<@fa<formal_derived_type_definition ::=
+     [>@ft<@b<abstract>>@fa<] >@ft<@b<new>>@fa< subtype_mark [[>@ft<@b<and>>@fa< interface_list] >@ft<@b<with private>>@fa<]>>
+
+!corrigendum 12.5.1(15)
+
+@dinsa
+For a generic formal type with an @fa<unknown_discriminant_part>, the actual
+may, but need not, have discriminants, and may be definite or indefinite.
+@dinst
+The actual type shall be a descendant of every ancestor of the formal type.
+
+!corrigendum 12.5.5(01)
+
+The class determined for a formal interface type is the class of all
+interface types.
+
+@i<@s8<Syntax>>
+
+@xcode<@fa<formal_interface_type_definition ::= interface_type_definition>>
+
+@i<@s8<Legality Rules>>
+
+The actual type shall be an interface type.
+
+The actual type shall be a descendant of every ancestor of the formal type.
+
+The actual type shall be limited if and only if the formal type is limited.
+
+!corrigendum 13.14(7)
+
+@dinsa
+@xbullet<The declaration of a record extension causes freezing of the parent
+subtype.>
+@dinst
+@xbullet<The declaration of a specific descendant of an interface type freezes
+the interface type.>
+
+
 !ACATS test
 
-ACATS Tests should be constructed to test this feature.
+(Many) ACATS Tests should be constructed to test this feature.
 
 !appendix
+
+!topic Type conversions of derived types
+!reference RM-4.6(8-23), 7.3.1
+!date 1999-05-14
+!from Bob Duff
+!keywords type conversion, derived type
+!discussion
+
+Question:
+
+Is it always legal to convert between two untagged types if they have a
+common ancestor?  Is it always legal to convert between two tagged types
+if they have a common ancestor, and obey the additional restrictions of
+4.6(22-23)?
+
+The answers should be "Yes", but a literal reading of the RM implies
+"No" in some cases.
+
+Example:
+
+    package Type_Conversion is
+        type Root is private;
+    private
+        type Root is access all Integer;
+    end Type_Conversion;
+
+    package Type_Conversion.Son is
+        type Son_Type is new Root;
+    end Type_Conversion.Son;
+
+    with Type_Conversion.Son; use Type_Conversion.Son;
+    package Type_Conversion.Daughter is
+
+        type Daughter_Type is new Root;
+        Son_Var: Son_Type;
+        Daughter_Var: Daughter_Type;
+
+        A: Daughter_Type := Daughter_Type(Son_Var); -- Legal.
+        B: Son_Type := Son_Type(Daughter_Var);
+
+    private
+
+        -- Here, Daughter_Type becomes a general access type.
+
+        C: Daughter_Type := Daughter_Type(Son_Var); -- Illegal?!
+        D: Son_Type := Son_Type(Daughter_Var);
+
+    end Type_Conversion.Daughter;
+
+In the declaration of C, the target type is a general access type (by
+7.3.1) so 4.6(13) applies.  The source type is not an access-to-object
+type (when viewed from that place), so it's illegal.  4.6(21) does not
+apply, because the target type *is* included in one of the "above four
+cases".
+
+That's clearly not the intent of the language designers.
+
+Reasons:
+
+First of all, I think it would be incompatible with Ada 83 (although I'm
+not sure -- I don't have my Ada 83 RM at hand, and I've largely
+forgotten that language ;-)).  Certainly no such incompatibility was
+intended; no such incompatibility is listed under the "Incompatibilities
+with Ada 83" heading in the AARM.
+
+Second, consider the declaration of A.  It is clearly legal.  Why should
+moving it into the private part make it illegal?  Normally moving into a
+private part or body *increases* the things you're allowed to do.
+
+Third, if we remove "all" from the full declaration of Root, then the
+declaration of C is clearly legal, because then 4.6(21) applies; it
+would be very strange for the "all" to have this effect.
+
+Fourth, the intent is that 4.6(21-23) should always be applicable, and
+that's the only sensible rule; this problem is merely an accident of
+wording.
+
+Note that the same wording problem arises for the special cases
+mentioned in 4.6(8,9,18) -- numerics, arrays, and, access-to-subprogram.
+I hesitate to suggest wording changes, but here's a timid attempt: Move
+4.6(21-23) earlier, before all the special cases, and make it clear that
+the special cases only apply when the "common ancestor" case doesn't.
+
+Current behavior of some compilers: As of yesterday, the Averstar front
+end finds it illegal, but I've changed it to make it legal, in
+anticipation of the expected ARG ruling.  The Rational compiler finds it
+legal.  The GNAT compiler (version 3.11p) doesn't complain about the
+declaration of C, but complains on the declaration of D that Son_Type is
+not visible.  If I remove D, GNAT is happy, so that's apparently a bug
+not directly related to this issue.
+
+Note: I tripped over this problem in real code I was modifying (in our
+run-time system); I changed an "access" to "access all", and some type
+conversions suddenly became illegal (according to our compiler).  The
+comments in the compiler sent me to 4.6(13), and I was surprised to find
+that it was doing exactly what the RM literally says.
+
+- Bob
+
+****************************************************************
 
 !from Tucker Taft
 !date Saturday, November 25, 2000 1:51 PM

Questions? Ask the ACAA Technical Agent