Version 1.1 of ais/ai-00416.txt

Unformatted version of ais/ai-00416.txt version 1.1
Other versions for file ais/ai-00416.txt

!standard 3.9.2(2)          05-02-07 AI95-00416/01
!class amendment 05-02-07
!status work item 05-02-07
!status received 05-02-07
!priority High
!difficulty Hard
!subject Access results, accessibility, and return statements
!summary
Dispatching on access result is supported.
Tasks are activated after returning from a function that returns an object containing tasks.
Accessibility levels are defined both for the call site, and at the point of the return statement, which is important for objects with access discriminants and for objects of a class-wide type.
!problem
We have not fully specified the rules for functions with anonymous access type as a result type. In particular, how do they work with dispatching and what are the accessibility rules.
We have also not specified the details for result types with access discriminants, as these have special accessibility considerations.
In general, we need to specify the accessibility level of the "return object" given that it might be aliased, have access discriminants, be an object of an anonymous access type, etc.
We also need to specify some of the details of what happens if the return object has a controlled or task part.
!proposal
Dispatching on access result is possible. For example:
function Empty_Acc return access T;
function Similar(X : access T; Y : access T) return Boolean; ...
M : access T'Class := ... B : Boolean := Similar(M, Empty_Acc);
The tag of M.all determines which overriding of Empty_Acc is invoked. A call on a function with a controlling access result may be dereferenced and still be a dynamically tagged or tag indeterminate expression.
Defaults for controlling access parameters should be permitted, so long as they are functions with controlling access results.
Caller does not pass in an accessibility level for return objects.
Return object has accessibility between uplevels and parameters. Hence:
Ok for return obj to point to up-levels Ok for locals to point to return obj Not Ok for up-levels to point to return obj Not Ok for return obj to point to locals
Function call has accessibility level of function decl, so may not use call on local function to initialize object in longer-lived heap if it has an access discrim or is of a class-wide type.
Tasks not activated until outermost enclosing object fully and successfully initialized. Certainly not prior to return, since only caller knows extent of outermost enclosing object.
!wording
Change first sentence of 3.2.3(1):
An operation operates on a type T if it yields a value of type T, if it has an operand whose expected type (see 8.6) is T, or if it has an access parameter {or access result type} (see 6.1) designating T.
Add to end of 3.9.2(2/2):
{Similarly, if the call is to a function with access result type designating T, then the call has a controlling access result, and the context can similarly control dispatching.}
Change 3.9.2(4):
... if it is a call with a controlling result {or access result}, ...
Change 3.9.2(5):
... or it is a call with a controlling result {or access result} and ...
Change 3.9.2(6):
... if it is a call with a controlling result {or access result}, ...
Delete the second sentence of 3.9.2(11):
The default_expression for a controlling formal parameter of a dispatching operation shall be tag indeterminate. [A controlling formal parameter that is an access parameter shall not have a default_expression.]
Delete 3.9.2(11.b) (it explained the second sentence of 3.9.2(11)).
Change 3.9.2(18/2):
* If the call has a controlling result {or access result} and is itself a (possibly parenthesized[ or]{,} qualified{, or dereferenced}) controlling operand...
Change 3.9.2(18.1/2):
* If the call has a controlling result {or access result} and is the [(possibly parenthesized or qualified)] expression {(possibly parenthesized, qualified, or as a dereference)} of an assignment_statement whose target is of a class-wide type, then its controlling tag value is determined by the target;
Replace 3.10.2(10/2) with:
* The accessibility level of the result of a function call that is used as the prefix of a name (directly or after a view conversion), is that of the nearest enclosing master.
AARM Note:
This is relevant when the function call is used as a prefix in a name that denotes an Access attribute or an access discriminant. In other contexts, the function call is being used to initialize some other object which then has its own well-defined accessibility level (e.g., when used in an initialized allocator, or as the initial expression in a declaration, or as an actual parameter).
Add after 3.10.2(10/2):
* Within a return_statement, the accessibility level of the return object is not known. For the purpose of dynamic accessibility checks, the level is considered to be deeper than that of the master that elaborated the function body, but not as deep as that of the current execution of the function.
AARM Note:
This definition is intended to ensure that any dynamic accessibility checks associated with converting to an access discriminant of such a return object will fail, unless the access value being converted designates an object that lives at least as long as the function body. But the object is not certain to itself live as long as the function body, since a caller might be assigning the result into one of its local variables, and so for checks on whether the return object lives as long as some object that might point at it, the deeper accessibility level is used.
Add after 3.10.2(18):
* Within a return_statement, the accessibility level of the return object is statically deeper than that of the master that elaborated the function body, and statically less deep than that of the current execution of the function.
Change 3.10.2(14):
* The accessibility level of an object {or constrained subtype} created by an allocator is the same as that of the access type.
AARM Note:
We include constrained subtype here in the case where an uninitialized allocator specifies a constraint on an access discriminant (see 3.10.2(12)).
Add after 4.8(5.1/2):
If the designated type of the allocator has one or more access discriminants, then the accessibility level associated with the value of these discriminants shall not be statically deeper than that of the type of the allocator. The accessibility level associated with such access discriminants is determined as follows:
* For an uninitialized_allocator where the subtype_indication includes a subtype_mark that denotes a constrained subtype, the accessibility level of this subtype;
* For an initialized_allocator where the operand of the qualified_expression is a name that denotes a part of a call on a function (possibly parenthesized, qualified, or converted), the accessibility level of the function;
* For an initialized_allocator where the operand of the qualified_expression is a name that denotes a preexisting object (as opposed to an aggregate), the accessibility level of that object;
* Otherwise, the accessibility level of the type of the allocator.
Change 4.8(7/2):
... is not deeper than that of the type of the allocator. {If the designated type of the allocator has one or more access discriminants, then a check is made that the accessibility level assocated with these access discriminants is not deeper than that of the type of the allocator.} Program_Error is raised if [this] {either such} check fails.
Add after 6.5(5.5/2):
AARM NOTE:
If the result type is controlled or has a controlled part, appropriate calls on Initialize or Adjust are performed prior to executing the handled_sequence_of_statements, unless of course if the initial expression is an aggregate (which requires build-in-place with no call on Adjust).
Change 6.5(6/2):
For the execution of a {simple_}return_statement, ...
Add after 6.5(6/2):
If the return object has any parts that are tasks, the activation of those tasks does not occur until after the function returns (see 9.2).
AARM NOTE:
Only the caller can know when task activations should take place, as it depends on the context of the call. If the function is being used to initialize the component of some larger object, then that entire object must be initialized before any task activations. Even after the outer object is fully initialized, task activations are still postponed until the "begin" at the end of the declarative part if the function is being used to initialize part of a declared object.
Add after 9.2(4):
For task objects whose outermost enclosing object is neither a declared object nor an object created by an allocator, activations are initiated after completing any initialization for this outermost enclosing object, prior to performing any other operation on the object. For a task that is created and returned as the result of a function call, activation does not occur until after the function returns.
AARM NOTE:
The intent is that "temporary" objects with task parts are treated similarly to an object created by an allocator. The "whole" object is initialized, and then all of the task parts are activated together. Each such "whole" object has its own task activation sequence, involving the activating task being suspended until all the new tasks complete their activation.
!discussion
(See proposal.)
!example
(See umm, er...imagine one here. - ED)
--!corrigendum 02.09(2)
!ACATS test
!appendix

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

Questions? Ask the ACAA Technical Agent