CVS difference for ais/ai-00202.txt

Differences between 1.1 and version 1.2
Log of other versions for file ais/ai-00202.txt

--- ais/ai-00202.txt	1998/09/30 00:17:36	1.1
+++ ais/ai-00202.txt	1998/10/03 04:28:56	1.2
@@ -1,24 +1,198 @@
-!standard 12.05.01 (21)                               98-03-27  AI95-00202/00
+!standard 12.05.01 (21)                               98-10-02  AI95-00202/01
 !class binding interpretation 98-03-27
+!status work item 98-10-02
 !status received 98-03-27
 !priority Medium
 !difficulty Hard
 !subject Primitives of formal type derived from another formal type
 
-!summary 98-03-27
+!summary 98-10-02
 
-
-!question 98-03-27
-
-
-!recommendation 98-03-27
-
-
-!wording 98-03-27
-
-
-!discussion 98-03-27
-
+When the ancestor type of a formal derived type is itself a formal type,
+then within an instance, the copies of the formal derived type's inherited
+primitive operations declare views of the formal ancestor type's operations.
+
+!question 98-10-02
+
+In an instance of a generic where a formal derived type whose ancestor type
+is another formal type, the rules regarding the meanings of the implicit
+declarations for the formal derived type produce a peculiar result.
+
+Consider the following example:
+
+   package P1 is
+      type R1 is record .. end record;
+      procedure S (x : R1);                  -- (1)
+   end P1;
+   use P1;
+
+   generic
+      type F2 is new R1;
+      -- implicit: procedure S (x : F2);     -- (2)
+      type F3 is new F2;
+      -- implicit: procedure S (x : F3);     -- (3)
+   procedure G (o2 : F2; o3 : F3);
+   procedure G (o2 : F2; o3 : F3) is
+   begin
+      S(o2);
+      S(o3);                                 -- Peculiar result
+   end G;
+
+   package P2 is
+      type R2 is new R1;
+      -- implicit: procedure S (x : R2);     -- (4)
+      procedure S (x : R2);                  -- (5)
+   end P2;
+   use P2;
+
+   package P3 is
+      type R3 is new R2;
+      -- implicit: procedure S (x : R3);     -- (6)
+      procedure S (x : R3);                  -- (7)
+   end P3;
+   use P3;
+
+   procedure I is new G(R2, R3);
+
+In the instance I, the implicit declarations of S which operate on F2 and F3,
+respectively are the corresponding primitive subprograms of the ancestor
+types of each type, as stated in RM95 12.5.1(21).  The ancestor type of F2 is
+R1, so the implicit declaration of S that operates on F2 (2) is a view of the
+corresponding primitive subprogram of R1 (1).
+
+The ancestor type of F3 is the type of the subtype denoted by the name F2 in
+the instance, which is R2.  So, the implicit declaration of S that operates
+on F3 (3) is a view of the corresponding primitive subprogram of R2 (5).
+But, the annotation in AARM 12.5.1(21.a) indicates that the reason the
+primitives of a formal derived type in an instance are views of its ancestor's
+primitives is because the primitives of its actual type might not be subtype
+conformant with those of its ancestor type.  This intention could be violated
+if the primitive S (3) is a view of the primitive S (5).
+
+Is it the intent that the primitive S (3) should instead declare a view
+of S (1)? (Yes.)
+
+In general, when the ancestor type of a formal derived type is itself
+another formal type, then within an instance does the derived type
+acquire the primitive operations of the formal ancestor type or the
+primitive operations of the ancestor type's corresponding actual type?
+(The derived type within the instance declares copies that are views
+of the operations of the formal ancestor type.)
+
+!recommendation 98-10-02
+
+When the ancestor type of a formal derived type is itself a formal type,
+then within an instance, the copies of the formal derived type's inherited
+primitive operations declare views of the formal ancestor type's operations,
+not views of the operations of the ancestor's corresponding actual type
+as suggested by 12.5.1(21).
+
+!wording 98-10-02
+
+???
+Revise 12.5.1(21) to say:
+
+  "... In an instance, the copy of such an implicit declaration declares
+   a view of the corresponding primitive subprogram {declared for the
+   ancestor type in the generic unit} [of the ancestor], ..."
+???
+
+!discussion 98-10-02
+
+The rule that defines the meaning of inherited operations of formal
+derived types (RM95-12.5.1(21)) states:
+
+  "For a formal derived type, the predefined operators and inherited
+   user-defined subprograms are determined by the ancestor type, and are
+   implicitly declared at the earliest place, if any, within the immediate
+   scope of the formal type, where the corresponding primitive subprogram
+   of the ancestor is visible (see 7.3.1).  In an instance, the copy of
+   such an implicit declaration declares a view of the corresponding primitive
+   subprogram of the ancestor, even if this primitive has been overridden for
+   the actual type."
+
+The second sentence asserts that the instance view of a formal derived
+type's primitive subprograms come from the ancestor type.  This rule
+is designed to avoid the semantic problems that could arise for an untagged
+formal derived type when the corresponding actual type has an overriding
+primitive subprogram that is not subtype conformant with the operation
+inherited from the ancestor.  For instance, the subtypes or modes of the
+actual subprogram might differ from that of the inherited subprogram
+leading to nonsense for calls made to the formal derived type's
+subprograms from within the generic.
+
+However, the wording of 12.5.1(21) does not properly account for the
+case where the ancestor of the formal derived type is itself a formal
+type.  Consider this example adapted from the example in the !question
+section:
+
+   package P1 is
+      type R1 is new Integer;
+      procedure S (X : in R1);               -- (1)
+   end P1;
+   use P1;
+
+   generic
+      type F2 is new R1;
+      -- implicit: procedure S (X : F2);     -- (2)
+      type F3 is new F2;
+      -- implicit: procedure S (X : F3);     -- (3)
+   procedure G (O2 : F2; O3 : F3);
+   procedure G (O2 : F2; O3 : F3) is
+   begin
+      S(O2);  -- (4) OK: calls view of R1's procedure S
+      S(O3);  -- (5) Call with constant actual: legal?
+   end G;
+
+   package P2 is
+      type R2 is new R1;
+      procedure S (X : in out R2);           -- (6)  Mode changes to 'in out'
+   end P2;
+   use P2;
+
+   package P3 is
+      type R3 is new R2;
+      procedure S (x : in R3);               -- (7)
+   end P3;
+   use P3;
+
+   procedure Instance is new G(R2, R3);
+
+The call to S for type F2 works fine, since 12.5.1(21) defines
+this to call the version of S inherited from type R1.  So even
+though the subprogram S associated with the actual type R2
+has a parameter of mode 'in out', in the instance the call
+at (4) will invoke the inherited subprogram S for type R1,
+which has an 'in' mode parameter.
+
+However, according to 12.5.1(21), the copy for procedure S for formal
+type F3 in Instance should be taken as a view of the corresponding
+operation of the ancestor type, and in the instance "the ancestor
+type" is interpreted as being a copy of the actual type associated
+with the formal ancestor (by virtue of the rules for generic
+instances in 12.3(5)).  Thus, since the actual for the formal
+ancestor type F2 is R2, the call at (5) should map into a call
+to the procedure S belonging to R2.  But the S declared at (7)
+has a parameter of mode 'in out', and that is inconsistent with
+the call at (5), which passes a constant (the in parameter O3)
+as an actual.  Thus we would have a generic contract model
+violation for calls within the body of the generic G.
+
+Clearly the call at (5) should also result in a call to the
+procedure S declared at (1).  In general we want the subprogram
+inherited by a formal derived type in an instance to correspond
+to a subprogram of known profile belonging to some ancestor
+of the immediate ancestor of the formal derived type in question
+(the nearest ancestor with a corresponding explicit subprogram).
+A possible wording that expresses this intent is to say that the
+copy of an inherited subprogram of a formal derived type declares
+a view of the corresponding primitive subprogram declared for the
+ancestor type in the generic unit.  This implicitly accounts for
+the potentially transitive nature of the required view.  [The
+wording may need some adjustment though, since technically it
+doesn't seem completely legitimate to refer to a primitive
+subprogram of a formal ancestor type when in the context of
+an instance, but the intended interpretation is clear enough.]
 
 !appendix 98-03-27
 

Questions? Ask the ACAA Technical Agent