CVS difference for ais/ai-00228.txt

Differences between 1.4 and version 1.5
Log of other versions for file ais/ai-00228.txt

--- ais/ai-00228.txt	2002/01/24 04:54:11	1.4
+++ ais/ai-00228.txt	2002/06/11 05:15:46	1.5
@@ -1,20 +1,21 @@
-!standard  3.09.3    (6)                             02-01-23  AI95-00228/01
-!class binding interpretation 00-04-10
+!standard  3.09.3    (6)                             02-05-24  AI95-00228/02
+!class ramification 02-05-24
 !status work item 02-01-23
 !status received 00-04-10
 !priority Low
 !difficulty Medium
 !qualifier Clarification
-!subject Premature use of "must be overridden" subprograms
+!subject Premature use of "shall be overridden" subprograms
 
 !summary
 
-A subprogram which 'shall be overridden' in the sense of 3.9.3(6) is subject
-to the same restrictions as an abstract subprogram.
+A subprogram which 'shall be overridden' in the sense of 3.9.3(6) is not
+subject to the restrictions that apply to an abstract subprogram. The 'shall be
+overriden' property doesn't apply to a renamed view.
 
 !question
 
-AI95-00211 states that "the 'shall be overridden' property of 3.9.3(6)  applies
+AI95-00211 states that "the 'shall be overridden' property of 3.9.3(6) applies
 to a renamed view. Thus, any renaming of an inherited subprogram that must be
 overridden is illegal."
 
@@ -25,158 +26,127 @@
    package Types is
        type T is abstract tagged null record;
        function F return T;
-       generic
-          type NT is new T with private;
-          with function NF return NT;
-       procedure G;
    end Types;
 
    with Types;
    package Extensions is
        type E is new Types.T with null record;
        type A is access function return E;
-       X : A := F'Access; -- Legal? (No.)
-       procedure I is new Types.G (E, F); -- Legal? (No.)
+       X : A := F'Access; -- Legal? (Yes.)
        function F return E;
    end Extensions;
 
-Hopefully the lines marked "Legal?" are actually illegal, otherwise it would
-be possible to create a reference to or call such a 'shall be overridden'
-subprogram.
-
-These are only some of the constructs that can cause trouble.  Between the
-place where E is declared and the place where F is overridden, it is for
-instance possible to use E as a generic actual parameter (and one wonders if
-the generic is able to call the inherited F) or to derive from E (and one
-wonders if the derived type inherits F, and if the inherited subprogram has
-the 'shall be overridden' property).
-
-!recommendation
-
-(See Wording.)
-
-!wording
-
-Replace 3.9.3(4) by:
-
-For a derived type, if the parent or ancestor type has an abstract or
-insubstantial primitive subprogram, or a primitive function with a controlling
-result, then:
-
-Replace the first sentence of 3.9.3(6) with:
-
-Otherwise, the subprogram is _insubstantial_; an insubstantial subprogram
-shall be overridden with a nonabstract subprogram; [for a type declared in the
-visible part of a package, the overriding may be either in the visible or the
-private part.]
-
-Replace 3.9.3(7) by:
-
-A call on an abstract or insubstantial subprogram shall be a dispatching call;
-[nondispatching calls to an abstract or insubstantial subprogram are not
-allowed.]
-
-Replace the second sentence of 3.9.3(9) with:
-
-If a generic formal type is abstract, then for each primitive subprogram of the
-formal that is neither abstract nor insubstantial, the corresponding primitive
-subprogram of the actual shall neither be abstract nor insubstantial.
-
-Replace 3.9.3(11) by:
-
-A generic actual subprogram shall not be an abstract or insubstantial
-subprogram. The prefix of an attribute_reference for the Access,
-Unchecked_Access, or Address attributes shall not denote an abstract or
-insubstantial subprogram.
-
-!discussion
-
-The subprograms which have the 'shall be overridden' property of 3.9.3(6) are
-very similar to abstract subprograms. However, they are not defined as
-abstract. This is quite strange, because it seems that all the rules in 3.9.3
-which have to do with abstract subprograms would be applicable to these
-'shall be overridden' subprograms. This is true in particular of 3.9.3(4),
-3.9.3(7), 3.9.3(9), and 3.9.3(11).
-
-We have two options. Either we change 3.9.3(6) to state that the 'shall be
-overridden' subprograms are actually abstract, and all the rules in 3.9.3 now
-prevent nasty usages of these subprograms. Or we invent a new term to designate
-them, and we complement some of the rules in 3.9.3 to forbid the usages that
-are known to be problematic.
-
-Archeology indicates that in version 4.0 of RM95, the rules of 3.9.3(6) were
-phrased in terms of abstract subprograms, and this was changed in version 5.0
-of RM95. This seems to indicate that the 4.0 formulation was inadequate; this
-is probably because this formulation had the consequence that nonabstract
-tagged types could have abstract subprograms.
-
-So we decide to create new terminology and fix various rules in 3.9.3: the
-subprograms covered by 3.9.3(6) are dubbed "insubstantial", and we change
-some rules to say "abstract or insubstantial".
-
-!corrigendum 3.9.3(4)
-
-@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
-For a derived type, if the parent or ancestor type has an abstract or
-insubstantial primitive subprogram, or a primitive function with a controlling
-result, then:
-
-!corrigendum 3.9.3(6)
-
-@drepl
-@xbullet<Otherwise, the subprogram shall be overridden with a nonabstract
-subprogram; for a type declared in the visible part of a package, the
-overriding may be either in the visible or the private part. However, if
-the type is a generic formal type, the subprogram need not be overridden
-for the formal type itself; a nonabstract version will necessarily be
-provided by the actual type.>
-@dby
-@xbullet<Otherwise, the subprogram is @i<insubstantial>; an insubstantial
-subprogram shall be overridden with a nonabstract subprogram; for a type
-declared in the visible part of a package, the overriding may be either in
-the visible or the private part. However, if the type is a generic formal type,
-the subprogram need not be overridden for the formal type itself; a nonabstract
-version will necessarily be provided by the actual type.>
-
-!corrigendum 3.9.3(7)
-
-@drepl
-A call on an abstract subprogram shall be a dispatching call;
-nondispatching calls to an abstract subprogram are not allowed.
-@dby
-A call on an abstract or insubstantial subprogram shall be a dispatching call;
-nondispatching calls to an abstract or insubstantial subprogram are not
-allowed.
-
-!corrigendum 3.9.3(9)
-
-@drepl
-If a partial view is not abstract, the corresponding full view shall not
-be abstract. If a generic formal type is abstract, then for each primitive
-subprogram of the formal that is not abstract, the corresponding primitive
-subprogram of the actual shall not be abstract.
-@dby
-If a partial view is not abstract, the corresponding full view shall not
-be abstract. If a generic formal type is abstract, then for each primitive
-subprogram of the formal that is neither abstract nor insubstantial, the
-corresponding primitive subprogram of the actual shall neither be abstract
-nor insubstantial.
-
-!corrigendum 3.9.3(11)
-
-@drepl
-A generic actual subprogram shall not be an abstract subprogram. The
-@fa<prefix> of an @fa<attribute_reference> for the Access, Unchecked_Access,
-or Address attributes shall not denote an abstract subprogram.
-@dby
-A generic actual subprogram shall not be an abstract or insubstantial
-subprogram. The @fa<prefix> of an @fa<attribute_reference> for the Access,
-Unchecked_Access, or Address attributes shall not denote an abstract
-or insubstantial subprogram.
+These are only some of the constructs that are problematic. Between the place
+where E is declared and the place where F is overridden, there are a number of
+constructs that could be used to ultimately call F. Are such constructs legal?
+(Yes.)
+
+!response
+
+The essence of the question revolves around the difference between "abstract"
+and "shall be overridden". AI95-00211 seems to have been written with the
+assumption that these terms were more or less synonymous, but in fact they are
+not. By definition, an abstract subprogram has no implementation, so we must
+prevent any contruct that could lead to non-dispatching calls to such a
+subprogram. On the other hand, the rules of RM95 3.9.3(6) ensure that an
+overrider will be provided for each "shall be overridden" subprogram, and that
+this overrider will not be abstract. So non-dispatching calls to such
+subprograms are fine, because we can guarantee that there exist a proper
+implementation.
 
+To illustrate the difference, consider the following example, which is somewhat
+similar to the one in the question, but shows several levels of derivation:
+
+    package P1 is
+        type T1 is abstract tagged ...;
+        function F return T1;
+        procedure P (A : T1) is abstract;
+    end P1;
+
+    with P1;
+    package P2 is
+        type T2 is new P1.T1 with ...;
+        -- Inherits an F and a P which shall be overridden.
+    private
+        function F return T2;
+        procedure P (A : T2);
+    end P2;
+
+    with P2;
+    package P3 is
+        type T3 is new P2.T2 with ...;
+        -- Inherits an F which shall be overridden.
+        function F return T3;
+    end P3;
+
+    with P1;
+    package P4 is
+        type T4 is new abstract P1.T1 with ...;
+        -- Inherits an F and a P which are abstract.
+    end P4;
+
+In package P2, T2 inherits two subprograms (F and P) which shall be overridden.
+In this instance the overrides appear in the private part, but at the point of
+the type declaration we know that an override is coming. So in the visible part
+of P2 it is legal to evaluate the attribute Access for F or P (note that most
+other usages of F or P are illegal in this example because they would freeze T2
+before its full definition). This wouldn't be true for abstract subprograms.
+
+In package P3, when we derive from P2.T2, there is no need to override the
+inherited P, because it has a perfectly good body (the one of the P declared in
+the private part of P2). On the other hand, P2.F being a function with a
+controlling result, it has to be overridden. Again, F'Access is legal in the
+specification of P3, even before the declaration of the overrider. Similarly, F
+may be called, used as a actual parameter to a generic instantiation, etc.
+
+In package P4, T4 is declared to be an abstract type, so the inherited F and P
+are abstract. They may or may not be overriden, but it is illegal, say, to
+evaluate F'Access before a non-abstract override has been given.
+
+Based on this analysis, let's look again at AI95-00211. This AI deals with
+renamings of "shall be overridden" subprograms, as shown in the following
+example:
+
+    package Types is
+        type T is abstract tagged ...;
+        procedure P (F : T) is abstract;
+    end Types;
+
+    with Types;
+    package Extensions is
+        type E is new Types.T with ...;
+        -- Inherits a P which shall be overridden.
+        procedure Pr (F : E) renames P;
+        procedure P (F : E);
+    end Extensions;
+
+Pr denotes a new view of P, and we know that P will ultimately be overridden.
+The overrider of P will actually provide a body for Pr, too, so there is no
+need for Pr to inherit the "shall be overridden" property. This is effectively
+repealing part of AI95-00211. [Author's note: a ramification repealed by
+another confirmation which says just the opposite; isn't it wonderful?]
+
+Another way to look at the same problem is to consider the case where the name
+being renamed is dynamic:
+
+    with Types;
+    package Extensions is
+        type E is new Types.T with ...;
+        -- Inherits a P which shall be overridden.
+        type A is access procedure (F : E);
+        X : A := P'Access;
+        procedure Pr (F : E) renames X.all;
+        procedure P (F : E);
+    end Extensions;
+
+If the attribute Access is legal, the renaming has to be legal, as there is no
+way that we can statically determine that X.all actually denotes a "shall be
+overridden" subprogram.
+
+An odd consequence of this analysis is that, although Pr occurs before the
+declaration of the override, it is not technically a squirelling renaming in
+the sense of AARM 8.5.4(8.g). [Author's note: Boy, I don't like this!]
+
 !ACATS test
 
 A B-Test should be created to test these rules, possibly added to an existing
@@ -573,6 +543,74 @@
 must-be-overridden subprogram - that is the name resolution. That is precisely
 the meaning of a call to F (as I demonstrated earlier) -- why should F'Access
 not be usable when a call is?
+
+*************************************************************
+
+From the minutes of the Cupertino ARG meeting (February 2002):
+
+Pascal explains the current version of the AI. We could reintroduce the notion
+of these being abstract, but that was the way it was in draft 4 of Ada 95, and
+it was changed for draft 5. So he introduced the notion of "insubstantial" to
+handle this.
+
+A long discussion about the meaning of abstract and "must be overridden"
+ensues. After several false starts, we look at the following example:
+
+    package P1 is
+        type T1 is abstract tagged ...
+        function F return T1;
+        procedure P (A : T1) is abstract;
+    end P1;
+
+    with P1;
+    package P2 is
+        type T2 is new P1.T1 ...
+        -- Is P'access allowed here?? [Yes.]
+    private
+        function F return T2;
+        procedure P (A : T2);
+    end P2;
+
+    with P2;
+    package P3 is
+        type T3 is new P2.T2 ... -- Legal (P is not abstract)
+        function F return T3;
+    end P3;
+
+    with P1;
+    package P4 is
+        type T2 is new abstract P1.T1 ...
+        -- P'Access is not allowed.
+    end P4;
+
+If the parent type has an abstract procedure, the inherited procedure is "must
+be overridden", but not abstract, so we can do anything with the inherited
+subprogram, and don't have to override it again when deriving from the derived
+type. The function case works the same, except that it is "must be overridden"
+when deriving from the derived type.
+
+Bob Duff explains that "we" (the MRT) defined this so that if you "know a real
+definition is coming", you can take advantage of it (that is, the abstract
+restrictions do not apply to it). So it is intentional that you can use these
+as if they are normally defined, because they must be before the end of a
+scope. This is the reason that "must be overridden" items are not defined to be
+abstract.
+
+Someone asks if P'Access freezes P? No, it could be in a default expression.
+
+Pascal expresses concern about name resolution, but is convinced that a call
+from outside would need to use the real body, so this should work. Pascal will
+make sure that AI-211 does not conflict.
+
+Tucker says that this AI is a tempest in teapot. He suggests that it should be
+a confirmation. Pascal says that we finally understand what these paragraphs
+mean.
+
+Pascal will rewrite the AI.
+
+Approve intent of the AI: 7-0-0
+
+[Editor's note: this is complete reversal from earlier discussions.]
 
 *************************************************************
 

Questions? Ask the ACAA Technical Agent