Version 1.1 of ai12s/ai12-0335-1.txt
!standard 13.11(21) 19-06-04 AI12-0335-1/01
!standard 13.11.4(21/3)
!standard 13.11.4(31/3)
!class binding interpretation 19-06-04
!status work item 19-06-04
!status received 19-05-19
!priority Low
!difficulty Easy
!qualifier Omission
!subject Dynamic accessibility check needed for some requeue targets
!summary
A dynamic accessibility check is added to requeue to cover cases where there
is no static check.
!question
9.5.4(6/3) gives a compile-time accessibility rule for requeue statements.
Should there be a corresponding dynamic accessibility check to handle the
cases that the static rule does not cover? (Yes.)
!recommendation
(See Summary.)
!wording
Replace 9.5.4(7/4)
The execution of a requeue_statement proceeds by first evaluating the
procedure_or_entry_name[Redundant:, including the prefix identifying the
target task or protected object and the expression identifying the entry
within entry family, if any]. Precondition checks are then performed
as for a call to the requeue target entry or subprogram. The
entry_body or accept_statement enclosing the requeue_statement is
then completed[Redundant:, finalized, and left (see 7.6.1)].
with
The execution of a requeue_statement proceeds in the following
sequence of steps:
1. Evaluate the procedure_or_entry_name[Redundant:, including the prefix
identifying the target task or protected object and the
expression identifying the entry within an entry family, if any].
2. A check is made that that accessibility level is not equal to or
deeper than the level of the innermost enclosing body or callable
construct.
AARM Discussion: This check can only fail if the statically deeper
relationship does not apply to the accessibility level of the
type of the target object.
3. Perform precondition checks as for a call to the requeue target
entry or subprogram.
4) The entry_body or accept_statement enclosing the
requeue_statement is then completed[Redundant:, finalized, and left
(see 7.6.1)].
!discussion
In many cases where we have a static accessibility rule saying "The
accessibility level of This shall not be statically deeper than the
accessibility level of That", there is a corresponding runtime check to
handle the cases involving dynamic accessibility levels that cannot be
handled statically.
There is no such dynamic rule for requeue statements. This probably was OK
for Ada 95, but not for Ada 2005 or later.
Consider this example:
requeue Some_Function_Call.Some_Entry;
where Some_Function_Call returns a task type or a protected type.
This one is statically prohibited by the following Legality Rule:
In a requeue_statement of an accept_statement of some task unit,
either the target object shall be a part of a formal parameter of the
accept_statement, or the accessibility level of the target object shall
not be equal to or statically deeper than any enclosing accept_statement
of the task unit. In a requeue_statement of an entry_body of some protected
unit, either the target object shall be a part of a formal parameter of the
entry_body, or the accessibility level of the target object shall not be
statically deeper than that of the entry_declaration for the entry_body.
No problem so far.
But now let's get a standalone object of an anonymous access type involved.
declare
Local_Var : aliased Some_Type;
Ptr : access Foo := Local_Var'access;
begin
requeue Ptr.all.Some_Entry;
The legality rule cited above doesn't prohibit this case because of the
following 3.10.2 rule:
The statically deeper relationship does not apply to the accessibility
level of the type of a stand-alone object of an anonymous access-to-object
type; that is, such an accessibility level is not considered to be
statically deeper, nor statically shallower, than any other.
The dynamic semantics of this example are at best unclear; a change of some
kind is needed to deal with such cases.
Other cases where the "statically deeper" relationship doesn't apply include
access parameters and generic formal types (this is described in the
immediately preceding 3.10.2 paragraph, but we don't care about the details
here; the stand-alone object case is enough to demonstrate the problem).
It seems clear that we want to either
a) change the legality rules so that this example is illegal; or
b) add a runtime accessibility check which this example will fail.
Ada generally takes the second approach (that is, a runtime accessibility
check) in this sort of situation because we don't want to disallow something
reasonable like:
Ptr : access Foo := Some_Library_Level_Object'access;
begin
requeue Ptr.all.Some_Entry;
or even more likely (assuming the type of Some_Parameter is library-level):
Ptr : access Foo := Some_Parameter.Some_Anon_Access_Component;
begin
requeue Ptr.all.Some_Entry;
Thus we take that approach here.
!ASIS
No ASIS effect.
!ACATS test
!appendix
****************************************************************
Questions? Ask the ACAA Technical Agent