Version 1.3 of ai05s/ai05-0042-1.txt
!standard 9.1(9.2/2) 07-11-28 AI05-0042-1/02
!standard 9.4(11.1/2)
!class binding interpretation 07-03-27
!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 sentenct 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 that 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 that 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 that 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 that 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