Version 1.7 of ai05s/ai05-0042-1.txt

Unformatted version of ai05s/ai05-0042-1.txt version 1.7
Other versions for file ai05s/ai05-0042-1.txt

!standard 9.1(9.2/2)          08-05-21 AI05-0042-1/04
!standard 9.4(11.1/2)
!class binding interpretation 07-03-27
!status Amendment 201Z 08-11-26
!status WG9 Approved 08-06-20
!status ARG Approved 9-0-0 06-11-11
!status work item 07-03-27
!status received 07-01-22
!priority Medium
!difficulty Medium
!qualifier Omission
!subject Overriding versus implemented-by
!summary
A subprogram that is implemented by an entry or by a protected subprogram is effectively overridden by an implicit subprogram which calls the entry or protected subprogram.
!question
As part of the introduction of synchronized interfaces, we added the notion of an operation being "implemented by" an entry or a protected operation. This is a concept which is related to overriding, but has subtle differences.
Unfortunately, there appears to be quite a few places where the RM says "overridden" and where it should probably have said "overridden or implemented by". Here is an example:
package Pkg1 is type Ifc is protected interface; procedure P1 (X : in out Ifc; Y : Integer) is abstract; procedure P2 (X : in out Ifc; Y : Integer) is abstract; end Pkg1;
package Pkg2 is protected type Prot is new Pkg1.Ifc with procedure P1 (Y : Integer); entry P2 (Y : Integer); end Prot; end Pkg2;
Presumably this code should be legal, but there is no doubt that it violates 3.9.3(6/2), since the operations P1 and P2 inherited by Prot are not overridden. Should this example be legal? (Yes.)
Similarly, 12.3(18) describes how overriding happens in an instance, with interesting differences between the visible part and the private part. Presumably there should be similar words for "implemented by", but there are not.
!recommendation
(See Summary.)
!wording
Modify the last sentence of 9.1(9.2/2):
If the first parameter of a primitive inherited subprogram is of the task type or an access parameter designating the task type, and there is an entry_declaration for a single entry with the same identifier within the task declaration, whose profile is type conformant with the prefixed view profile of the inherited subprogram, the inherited subprogram is said to be implemented by the conforming task entry {using an implicitly declared non-abstract subprogram which has the same profile as the inherited subprogram and which overrides it}.
AARM Reason: The part about the implicitly declared subprogram is needed so that a subprogram implemented by an entry is considered to be overridden for the purpose of the other rules of the language. Without it, it would for instance be illegal for an abstract subprogram to be implemented by an entry, because the abstract subprogram would not be overridden. The rules in 9.1(9.6/2-9.8/2) and 9.4(11.5/2-11.7/2) ensure that there is no conflict between the implicit overriding subprogram and a user-defined overriding subprogram.
Modify the last sentence of 9.4(11.1/2):
If the first parameter of a primitive inherited subprogram is of the protected type or an access parameter designating the protected type, and there is a protected_operation_declaration for a protected subprogram or single entry with the same identifier within the protected declaration, whose profile is type conformant with the prefixed view profile of the inherited subprogram, the inherited subprogram is said to be implemented by the conforming protected subprogram or entry {using an implicitly declared non-abstract subprogram which has the same profile as the inherited subprogram and which overrides it}.
!discussion
One possible fix would be to change "overridden" by "overridden or implemented by" everywhere. But there are 24 occurrences of "overridden" in the RM, and the occurrences of "overriding" would have to be checked too. That's unappealing. It seems more straightforward to reify the model that we have had in mind all along anyway, namely that there is an implicit override that acts as a wrapper to call the protected subprogram or entry.
!corrigendum 9.1(9.2/2)
Replace the paragraph:
For a task declaration with an interface_list, the task type inherits user-defined primitive subprograms from each progenitor type (see 3.9.4), in the same way that a derived type inherits user-defined primitive subprograms from its progenitor types (see 3.4). If the first parameter of a primitive inherited subprogram is of the task type or an access parameter designating the task type, and there is an entry_declaration for a single entry with the same identifier within the task declaration, whose profile is type conformant with the prefixed view profile of the inherited subprogram, the inherited subprogram is said to be implemented by the conforming task entry.
by:
For a task declaration with an interface_list, the task type inherits user-defined primitive subprograms from each progenitor type (see 3.9.4), in the same way that a derived type inherits user-defined primitive subprograms from its progenitor types (see 3.4). If the first parameter of a primitive inherited subprogram is of the task type or an access parameter designating the task type, and there is an entry_declaration for a single entry with the same identifier within the task declaration, whose profile is type conformant with the prefixed view profile of the inherited subprogram, the inherited subprogram is said to be implemented by the conforming task entry using an implicitly declared non-abstract subprogram which has the same profile as the inherited subprogram and which overrides it.
!corrigendum 9.4(11.1/2)
Replace the paragraph:
For a protected declaration with an interface_list, the protected type inherits user-defined primitive subprograms from each progenitor type (see 3.9.4), in the same way that a derived type inherits user-defined primitive subprograms from its progenitor types (see 3.4). If the first parameter of a primitive inherited subprogram is of the protected type or an access parameter designating the protected type, and there is a protected_operation_declaration for a protected subprogram or single entry with the same identifier within the protected declaration, whose profile is type conformant with the prefixed view profile of the inherited subprogram, the inherited subprogram is said to be implemented by the conforming protected subprogram or entry.
by:
For a protected declaration with an interface_list, the protected type inherits user-defined primitive subprograms from each progenitor type (see 3.9.4), in the same way that a derived type inherits user-defined primitive subprograms from its progenitor types (see 3.4). If the first parameter of a primitive inherited subprogram is of the protected type or an access parameter designating the protected type, and there is a protected_operation_declaration for a protected subprogram or single entry with the same identifier within the protected declaration, whose profile is type conformant with the prefixed view profile of the inherited subprogram, the inherited subprogram is said to be implemented by the conforming protected subprogram or entry using an implicitly declared non-abstract subprogram which has the same profile as the inherited subprogram and which overrides it.
!ACATS test
A C test should be written to ensure that a code fragment like the one in the
!question is actually accepted by implementations.
!appendix

From: Pascal Leroy
Date: Monday, January 22, 2007 10:30 PM

As part of the introduction of synchronized interfaces, we added the
notion of an operation being "implemented by" an entry or a protected
operation. This is a concept which is related to overriding, but has
subtle differences.

Unfortunately, there appears to be quite a few places where the RM says
"overridden" and where it should probably have said "overridden or
implemented by".  Here is an example:

    package Pkg1 is
        type Ifc is protected interface;
        procedure P1 (X : in out Ifc; Y : Integer) is abstract;
        procedure P2 (X : in out Ifc; Y : Integer) is abstract;
    end Pkg1;

    package Pkg2 is
        protected type Prot is new Pkg1.Ifc with
            procedure P1 (Y : Integer);
            entry P2 (Y : Integer);
        end Prot;
    end Pkg2;

Presumably this code should be legal, but there is no doubt that it
violates 3.9.3(6/2), since the operations P1 and P2 inherited by Prot are
not overridden.

Similarly, 12.3(18) describes how overriding happens in an instance, with
interesting differences between the visible part and the private part.
Presumably there should be similar words for "implemented by", but these
words are missing.

****************************************************************

From: Tucker Taft
Date: Monday, January 22, 2007 10:37 PM

I would prefer to solve this by saying that "under
such-and-such circumstances, the inherited operation
is overridden by an implicit operation that invokes
the corresponding entry or protected operation."
This way we can continue to say overridden and not
get into trouble.  Having to spread the "implemented by"
wording all over the place seems undesirable.

****************************************************************


Questions? Ask the ACAA Technical Agent