Version 1.15 of ais/ai-00416.txt
!standard 3.2.3(01) 06-01-13 AI95-00416/14
!standard 3.3(10)
!standard 3.7(27)
!standard 3.9.2(02)
!standard 3.9.2(04)
!standard 3.9.2(05)
!standard 3.9.2(06)
!standard 3.9.2(11)
!standard 3.9.2(18)
!standard 3.10.2(07)
!standard 3.10.2(09)
!standard 3.10.2(10)
!standard 3.10.2(11)
!standard 3.10.2(12)
!standard 3.10.2(13)
!standard 3.10.2(14)
!standard 4.8(05)
!standard 4.8(10)
!standard 6.5(05)
!standard 6.5(06)
!standard 6.5(20)
!standard 6.5(22)
!standard 7.6.1(03)
!standard 7.6.1(09)
!standard 9.2(02)
!standard 9.2(03)
!standard 9.2(04)
!standard 9.3(02)
!standard 9.3(03)
!standard 13.11(25)
!standard 13.11.1(3)
!standard 13.11.2(9)
!standard 13.11.2(10)
!standard 13.11.2(17)
!class amendment 05-02-07
!status Amendment 200Y 05-03-16
!status ARG Approved 8-0-1 05-04-18
!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, but
nulls are allowed.
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.
A return object has accessibility between the uplevels of the function
and the return statement. Hence:
Ok for a return object to point to up-levels
Ok for locals of return statement to point to return object
Not Ok for locals outside return statement to point to return object
Not Ok for up-levels to point to return object
Not Ok for return object to point to locals
Function call has accessibility level of function declaration, so may not use
a call on a local function to initialize an object in a longer-lived heap if it
has an access discriminant or is of a class-wide type.
If access discriminants are initialized individually, then type
conversion provides for the accessibility checks. However, if the
access discriminants are not specified individually, but rather come
from a named constrained subtype, or from an initializing object, then
there is no type conversion involved, and hence we need an explicit rule
for the needed accessibility check. This is relevant at a function
return and at an allocator. At a function return, we can be returning a
record aggregate (access discriminants given individually), an extension
aggregate (access discriminants could come from ancestor part, either
from an object or named constrained subtype, or from individual values
specified after the "with"), a part of an existing object, a part of a
function call (level based on level of function decl). At an allocator
we have all of these possibilities, plus we have an unitialized
allocator where the subtype_indication denotes a named constrained
subtype, or an uninitialized allocator where the subtype_indication
contains an explicit constraint (access discriminants specified
individually).
---------------------
Tasks are not activated until outermost enclosing object fully and
successfully initialized, and certainly not prior to return, since only
caller knows extent of outermost enclosing object. A return object
that is not successfully initialized, is finalized prior to exiting
the return statement.
!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.
Change 3.3(10) as follows:
* {the return object created as} the result of evaluating a function_call
(or the equivalent operator invocation - see 6.6);
Change 3.7(27) to:
For an access discriminant, its access_definition is elaborated when
the value of the access discriminant is defined: by
evaluation of its default_expression, by elaboration of a
discriminant_constraint, or by an assignment that initializes the
enclosing object.
Add to end of 3.9.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 controlling
access result}, ...
Change 3.9.2(5):
... or it is a call with a controlling result {or controlling
access result} and ...
Change 3.9.2(6):
... if it is a call with a controlling result {or controlling
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):
* If the call has a controlling result {or controlling access result} and
is itself{, or designates,} a (possibly parenthesized or qualified)
controlling operand of an enclosing call on a dispatching operation of a
descendant of type T, then its controlling tag value is determined
by the controlling tag value of this enclosing call;
Change the paragraph inserted by AI95-00196 after 3.9.2(18):
* If the call has a controlling result {or controlling access result} and
{(possibly parenthesized, qualified, or dereferenced)} is the
[(possibly parenthesized or qualified)] expression of an
assignment_statement whose target is of a class-wide type, then
its controlling tag value is determined by the target;
Add after 3.10(12):
AARM NOTE:
Note that we considered imposing a similar implicit null exclusion
for controlling access results, but chose not to do that, because
there is no Ada95 compatibility issue, and there is no automatic
null check inherent in the use of a controlling access result. If a
null check is necessary, it is because there is a dereference of the
result, or because the value is passed to a null-excluding parameter.
If there is no dereference of the result, a null return
value is perfectly acceptable, and can be a useful indication of a
particular status of the call.
Modify 3.10.2(7/2) as follows:
* An entity or view [created by a declaration] {defined by a declaration and
created as part of its elaboration} has the same accessibility
level as the innermost [enclosing] master that elaborates the
declaration [other than] {of} the declaration [itself] except in the
cases of renaming and derived access types described below. A
parameter of a master has the same accessibility level as the
master.
AARM NOTE:
This rule defines the accessibility of all named access types, as
well as the accessibility level of all anonymous access types other
than those for access parameters and access discriminants. Special
rules exist for the accessibility level of such anonymous types.
Components, stand-alone objects, and function results whose
(anonymous) type is defined by an access_definition have
accessibility levels corresponding to named access types defined at
the same point.
Ramification: {AI95-00230-01} Because accessibility level
is determined by where the access_definition is elaborated,
for a type extension, the anonymous access types of
components (other than access discriminants) inherited
from the parent have the same accessibility as they did in the
parent; those in the extension part have the accessibility
determined by the scope where the type extension is declared.
Similarly, the types of the non-discriminant access components
of a derived untagged type have the same accessibility as they
did in the parent.
Change 3.10.2(9) as follows:
* The accessibility level of a view conversion{, qualified_expression,
or parenthesized expression,} is the same as that of the operand.
Replace 3.10.2(10) with:
* The accessibility level of an aggregate or the result of a function call
(or equivalent use of an operator) that is used (in its entirety) to
directly initialize part of an object is that of the object being
initialized. In other contexts, the accessibility level of an aggregate
or the result of a function call is that of the innermost master
that evaluates the aggregate or function call.
Add after 3.10.2(10):
* Within a return statement, the accessibility level of the return
object is that of the execution of the return statement. If the
return statement completes normally by returning from the
function, then prior to leaving the function, the accessibility level
of the return object changes to be a level determined by the point
of call, as does the level of any coextensions (see below) of the
return object.
AARM Note:
We define the accessibility level of the return object during the
return statement to be that of the return statement itself
so that the object may be designated by objects local to the
return statement, but not by objects outside the return statement.
In addition, the intent is that the return object gets finalized
if the return statement ends without actually returning (for example,
due to propagating an exception, or a goto). For a normal return,
of course, no finalization is done before returning.
Delete the paragraph added by AI95-00385 after 3.10.2(11) (it is redundant).
Change 3.10.2(12) to be:
* The accessibility level of the anonymous access type of an access
discriminant in the subtype_indication or qualified_expression of an
allocator, or in the expression or return_subtype_indication of
a return statement is determined as follows:
+ If the value of the access discriminant is determined by a
discriminant_association in a subtype_indication, the
accessibility level of the object or subprogram designated by
the associated value (or library level if the value is null);
AARM NOTE: This deals with the following cases,
when they occur in the context of an allocator or return statement:
- Extension aggregate where ancestor part is a subtype_mark
denoting a constrained subtype;
- Uninitialized allocator where subtype_indication defines
a constrained subtype;
- Discriminant of object with a constrained nominal subtype,
including constrained components, the result of calling
a function with a constrained result subtype, the dereference
of an access-to-constrained subtype, etc.
+ If the value of the access discriminant is determined by a
component_association in an aggregate, the accessibility
level of the object or subprogram designated by the associated
value (or library level if the value is null);
AARM NOTE: In this bullet, the aggregate has to occur in the
context of an allocator or return statement, while the
subtype_indication of the previous bullet can occur anywhere
(it doesn't have to be directly given in the allocator or
return statement).
+ In other cases, where the value of the access discriminant
is determined by an object with an unconstrained
nominal subtype, the accessibility level of the object.
AARM NOTE: In other words, if you know the value of the discriminant
for an allocator or return statement from a discriminant constraint or
an aggregate component association, then that determines the
accessibility level; if you don't know it, then it is based on the
object itself.
* The accessibility level of the anonymous access type of an access
discriminant in any other contect is that of the enclosing object.
Delete 3.10.2(12.a/2) (it was moved up to be after paragraph 7/2).
Delete the second paragraph inserted by AI95-00318 after 3.10.2(13) (it is redundant).
Change 3.10.2(14):
* The accessibility level of an object created by an allocator is
the same as that of the access type, except for an allocator of an
anonymous access type that defines the value of an access
parameter or an access discriminant. For an allocator defining the
value of an access parameter, the accessibility level is that of
the innermost master of the call. For one defining an
access discriminant, the accessibility level is determined as
follows:
+ for an allocator used to define the constraint in a
subtype_declaration, the level of the subtype_declaration;
+ for an allocator used to define the constraint in a
component_definition, the level of the enclosing type;
+ for an allocator used to define the discriminant of an object,
the level of the object.
In this last case, the allocated object is said to be a coextension
of the object whose discriminant designates it, as well as of any
object of which the discriminated object is itself a coextension or
subcomponent. All coextensions of an object are finalized
when the object is finalized (see 7.6.1).
AARM NOTE: The rules of access discriminants are such that
when the space for an object with a coextension is reclaimed,
the space for the coextensions can be reclaimed. Hence, there
is implementation advice (see 13.11) that an object and its coextensions
all be allocated from the same storage pool (or stack frame,
in the case of a declared object).
Add after 3.10.2(16):
In the above rules, the
operand of a view conversion, parenthesized expression or qualified_expression
is considered to be used in a context if the view conversion,
parenthesized expression or qualified_expression itself is used in that
context.
Add after the paragraph inserted by AI95-00344 after 4.8(5):
If the designated subtype of the type of the allocator has one or
more unconstrained access discriminants, then the accessibility
level of the anonymous access type of each access discriminant, as
determined by the subtype_indication or qualified_expression of the
allocator, shall not be statically deeper than that of the type of
the allocator (see 3.10.2).
Move the text added to 4.8(7) by AI95-00344 to after 4.8(10), and modify
it as follows:
{For any allocator,} if the designated type of the type of the
allocator is class-wide, then a check is made that the accessibility
level of the type determined by the subtype_indication,
or by the tag of the value of the qualified_expression,
is not deeper than that of the type of the allocator. {If the
designated subtype of the allocator has one or more unconstrained
access discriminants, then a check is made that the accessibility
level of the anonymous access type of each access discriminant is
not deeper than that of the type of the allocator.} Program_Error
is raised if [this] {either such} check fails.
Add after the third paragraph inserted by AI95-00318 after 6.5(5):
If the result subtype of the function is class-wide, the accessibility
level of the type of the expression of the return statement shall not be
statically deeper than that of the master that elaborated the function body.
If the result subtype has one or more unconstrained access discriminants,
the accessibility level of the anonymous access type of each access
discriminant, as determined by the expression of the
simple_return_statement or the return_subtype_indication, shall not be
statically deeper than that of the master that elaborated the function
body.
AARM NOTE:
We know that if the result type is class wide, then there must be
a return expression. Similarly, if the result subtype is unconstrained,
then either the return_subtype_indication (if any) is constrained,
or there must be a return expression.
Modify the paragraph inserted before 6.5(6) by AI95-00318:
For the execution of an extended_return_statement, the
subtype_indication or access_definition is elaborated. This creates
the nominal subtype of the return object. If there is a return
expression, it is evaluated and converted to the nominal subtype
(which might raise Constraint_Error - see 4.6){; the return object
is created} and {the converted value} becomes the initial value of
the return object; otherwise, the return object is {created and}
initialized by default as for a stand-alone object of its nominal
subtype (see 3.3.1). If the nominal subtype is indefinite, the
return object is constrained by its initial value. The
handled_sequence_of_statements, if any, is then executed.
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, except when the
initial expression is an aggregate (which requires build-in-place
with no call on Adjust).
If the return statement exits without resulting in a return (for example,
due to an exception propagated from the expression or the
handled_sequence_of_statements, or a goto out of the
handled_sequence_of_statements), the return object is finalized prior to
leaving the return statement.
Add after 6.5(6):
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.
Change the paragraph inserted by AI95-00318 after 6.5(20):
If the result type is class-wide, a check is made that the
accessibility level of the type identified by the tag of the result
is not deeper than that of the master that elaborated the function
body. {If the result subtype has one or more unconstrained access
discriminants, a check is made that the accessibility level of the
anonymous access type of each access discriminant, as determined by the
expression of the simple_return_statement or the return_subtype_indication,
is not deeper than that of the master that elaborated the function body.}
If [this] {either} check fails, Program_Error is raised.
Add after 6.5(22/2):
Implementation Permission
If the result subtype of a function is unconstrained,
and a call on the function is used, directly or indirectly,
to provide the initial value of
an object with a constrained nominal subtype, Constraint_Error may
be raised at the point of the call (after abandoning the
execution of the function body) if, while elaborating the
return_subtype_indication or evaluating the expression of a return
statement that applies to the function body, it is determined that the
value of the result will violate the constraint of this object's subtype.
AARM NOTE: Without such a permission, it would be very difficult
to implement "build-in-place" semantics. Such an exception is not
handleable within the function, because in the return-by-copy
case, the constraint check to verify that the result satisfies the
constraints of the object being initialized happens after the
function returns, and we want the semantics to change as
little as possible when switching between
return-by-copy and build-in-place.
This implies further that upon detecting such a situation, the
implementation may need to simulate a goto to a point outside any
local exception handlers prior to raising the exception.
Change 7.6.1(3) as amended by AI95-00162:
... except in the case of a master: the execution of a body other
than a package_body; [the elaboration of a declaration other than
the declaration of a package; ] the execution of [an accept_statement,
a block_statement, or a simple_statement] {a statement}; or the
evaluation of an expression{, function_call,} or range that is not part of
an enclosing expression, {function_call,} range, or simple_statement
{other than a simple_return_statement}...
Add after 7.6.1(9):
* If the object has coextensions (see 3.10.2), each coextension is finalized
after the object whose access discriminant designates it.
Change 9.2(2):
A task object (which represents one task) can be {a part
of a stand-alone object, of an object created by an allocator, or of an
anonymous object of a limited type, or a coextension of one of these}
[created either as part of the
elaboration of an object_declaration occurring immediately within
some declarative region, or as part of the evaluation of an
allocator]. All tasks {that are part or coextensions of any of the
stand-alone objects}
created by the elaboration of object_declarations {(or
generic_associations of formal objects of mode IN)} of a single
declarative region [(including subcomponents of the declared
objects)] are activated together. [Similarly, all tasks created by
the evaluation of a single allocator are activated together. The
activation of a task is associated with the innermost allocator or
object_declaration that is responsible for its creation.] {All
tasks that are part or coextensions of a single object that is not a
stand-alone object are activated together.}
Change 9.2(3):
For {the} tasks [created by the elaboration of object_declarations] of a
given declarative region, the activations are initiated within the
context of the handled_sequence_of_statements ...
Change 9.2(4):
{For tasks that are part or coextensions of a single object that is
not a stand-alone object, activations are initiated after completing any
initialization of the outermost object enclosing these tasks, prior
to performing any other operation on the outermost object. In
particular, for} [For] tasks {that are part or coextensions of the
object} created
by the evaluation of an allocator, the activations are initiated as
the last step of evaluating the allocator, [after completing any
initialization for the object created by the allocator, and] prior
to returning the new access value. {For tasks that are part or
coextensions of an
object that is the result of a function call, the activations are
not initiated until after the function returns.}
AARM NOTE:
The intent is that "temporary" objects with task parts (or coextensions)
are treated similarly to an object created by an allocator. The "whole"
object is initialized, and then all of the task parts (including the
coextensions) 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.
Drop the changes to paragraphs 9.3(2) and 9.3(3) added by AI-162. Add after
9.3(3):
* Otherwise, the task depends on the
master of the outermost object of which it is a part (as
determined by the accessibility level of that object -- see
3.10.2 and 7.6.1), as well as on any master whose execution
includes that of the master of the outermost object.
AARM NOTE: The master of a task created by a return
statement changes when the accessibility of the return
object changes. Note that its activation happens, if at
all, only after the function returns and all
accessibility level changes have occurred.
Change the first bullet added by the replacement of 13.11(25) in AI-230
as follows:
* If the allocator is [initializing an access discriminant of an object
of a limited type, and the discriminant is itself a subcomponent]
{defining a coextension (see 3.10.2)}
of an object being created by an outer allocator, then the storage
pool used for the outer allocator should also be used for the
[allocator initializing the access discriminant] {coextension};
Change 13.11.2(9) as follows:
3. Free(X), when X is not equal to null first performs finalization {of
the object designated by X (and any coextensions of the object --
see 3.10.2)}, as described in 7.6{.1}. It then deallocates the storage
occupied by the object designated by X {(and any coextensions)}. If
the storage pool is a user-defined object, then the storage is
deallocated by calling Deallocate, passing
access_to_variable_subtype_name'Storage_Pool as the Pool
parameter. Storage_Address is the value returned in the
Storage_Address parameter of the corresponding Allocate call.
Size_In_Storage_Elements and Alignment are the same values passed
to the corresponding Allocate call. There is one exception: if the
object being freed contains tasks, the object might not be
deallocated.
Change 13.11.2(10) as follows:
After Free(X), the object designated by X, and any subcomponents {(and
coextensions)} thereof, no longer exist; their storage can be reused
for other purposes.
Delete the paragraph added after 13.11.2(17) by AI-162.
!discussion
Our intent is to define the checks needed when an object with
access discriminants is initialized by assignment as equivalent
to converting each access discriminant to
the type of the access discriminant of the target.
When a function call is used as a prefix (or as an actual parameter), such
as for taking 'Access or selecting a component, it is considered
a temporary object, and the accessibility level of an access discriminant
subcomponent will have the level of the nearest enclosing master.
On the other hand, if the function call is used as a "whole" to initialize
an allocator, a declared object, or a return object, it takes on the
accessibility level of the function declaration.
We want to preserve the model that an allocator (of an anonymous type)
that is used to initialize an access discriminant results in an
allocated object that has the same storage pool and lifetime as the
object with the access discriminant. This should be true whether
the enclosing object is limited or non-limited.
We have defined a new term, "coextension," to describe an
object created by an allocator of an anonymous type that is
being used to initialize an access discriminant of an "outer" object.
An object and all its coextensions are allocated, initialized,
finalized, and freed at the same point, as though the coextensions
are components of the object.
For a limited function return, the caller has to control where the
return object is built. If the result subtype is unconstrained, while
the call is being used to initialize a constrained object, including a
component, the space available to the object is bounded. To avoid
overrunning this space, the caller must pass in some sort of implicit
parameters which will allow the return statement to determine the limits
on the space it may occupy. One possibility is to pass in the values
for the discriminants, or perhaps to preeinitialize them in the space
for the return object. There should be an implementation permission to
allow raising Constraint_Error at the beginning of the return statement,
prior to fully evaluating the expression of a simple return or executing the
handled sequence of statements. Something analogous to a 'Constrained bit can
be provided, to indicate whether the discriminant values are preinitialized.
-----------------
Our last discussion about access discriminants
and allocators in Paris was a bit concerning,
I'm sure. For what it's worth, I believe I have
worked out all the problems, and the "joined at
the hip" model will work for nonlimited types
as well. Generally, the solution is to return
more closely to the rule that an access discriminant
always has the same level as the object it is
a component of. I had broken that rule for objects
returned by functions when referring to an
access discriminant of a subcomponent of the
result, and that was causing the trouble, I
believe. Calling a function and then only using
a part of the result is quite rare, and using
a part that happens to have an access discriminant
that is initialized from the enclosing object's
access discriminant is well below the noise
level.
Overall, the general rule becomes that as soon
as you select a component of a function result,
the function result is treated as a "temp",
and it takes on a very local accessibility
level, as do any access discriminants it has.
E.g.:
X : T := func().component;
is not permitted if component has an access
discriminant initialized from the enclosing object,
because the call is a temp, and we are
trying to initialize a longer-lasting
object. Another way to think about it is
that only when "build-in-place" is possible
can the result of the function call be long-lived.
!example
(See umm, er...imagine one here. - ED)
!corrigendum 3.2.3(01)
Replace the paragraph:
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 (see 6.1) designating T. A predefined operator, or other
language-defined operation such as assignment or a membership test, that
operates on a type, is called a predefined operation of the type. The
primitive operations of a type are the predefined operations of the type,
plus any user-defined primitive subprograms.
by:
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. A
predefined operator, or other language-defined operation such as assignment or
a membership test, that operates on a type, is called a predefined
operation of the type. The primitive operations of a type are the
predefined operations of the type, plus any user-defined primitive subprograms.
!corrigendum 3.3(10)
Replace the paragraph:
- the result of evaluating
a function_call (or the equivalent operator invocation — see 6.6);
by:
- the return object created as the result of evaluating
a function_call (or the equivalent operator invocation — see 6.6);
!corrigendum 3.7(27)
Replace the paragraph:
An access_definition is elaborated when the value of a corresponding
access discriminant is defined, either by evaluation of its
default_expression or by elaboration of a discriminant_constraint.
The elaboration of an access_definition creates the anonymous access
type. When the expression defining the access discriminant is evaluated, it is
converted to this anonymous access type (see 4.6).
by:
For an access discriminant, its access_definition is elaborated when
the value of the access discriminant is defined: by
evaluation of its default_expression, by elaboration of a
discriminant_constraint, or by an assignment that initializes the
enclosing object.
!corrigendum 3.9.2(02)
!comment This includes the wording change from AI-260-2.
@drepl
A @i<call on a dispatching operation> is a call whose @fa<name> or @fa<prefix>
denotes the declaration of a primitive subprogram of a tagged type, that is, a
dispatching operation. A @i<controlling operand> in a call on a dispatching
operation of a tagged type @i<T> is one whose corresponding formal parameter is
of type @i<T> or is of an anonymous access type with designated type @i<T>; the
corresponding formal parameter is called a @i<controlling formal parameter>. If
the controlling formal parameter is an access parameter, the controlling
operand is the object designated by the actual parameter, rather than the
actual parameter itself. If the call is to a (primitive) function with result
type @i<T>, then the call has a @i<controlling result> -- the context of the
call can control the dispatching.
@dby
A @i<call on a dispatching operation> is a call whose @fa<name> or @fa<prefix>
denotes the declaration of a dispatching operation. A @i<controlling operand>
in a call on a dispatching operation of a tagged type @i<T> is one whose
corresponding formal parameter is of type @i<T> or is of an anonymous access
type with designated type @i<T>; the corresponding formal parameter is called a
@i<controlling formal parameter>. If the controlling formal parameter is an
access parameter, the controlling operand is the object designated by the
actual parameter, rather than the actual parameter itself. If the call is to a
(primitive) function with result type @i<T>, then the call has a @i<controlling
result> -- the context of the call can control the dispatching. Similarly, if
the call is to a function with access result type designating @i<T>, then the
call has a @i<controlling access result>, and the context can similarly control
dispatching.
!corrigendum 3.9.2(04)
Replace the paragraph:
- The name or expression is statically tagged if it is of a
specific tagged type and, if it is a call with a controlling result, it has at
least one statically tagged controlling operand;
by:
- The name or expression is statically tagged if it is of a
specific tagged type and, if it is a call with a controlling result or
controlling access result, it has at least one statically tagged controlling
operand;
!corrigendum 3.9.2(05)
Replace the paragraph:
- The name or expression is dynamically tagged if it is of a
class-wide type, or it is a call with a controlling result and at least one
dynamically tagged controlling operand;
by:
- The name or expression is dynamically tagged if it is of a
class-wide type, or it is a call with a controlling result or controlling
access result and at least one dynamically tagged controlling operand;
!corrigendum 3.9.2(06)
Replace the paragraph:
- The name or expression is tag indeterminate if it is a call
with a controlling result, all of whose controlling operands (if any) are tag
indeterminate.
by:
- The name or expression is tag indeterminate if it is a call
with a controlling result or controlling access result, all of whose
controlling operands (if any) are tag indeterminate.
!corrigendum 3.9.2(11)
Replace the paragraph:
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.
by:
The default_expression for a controlling formal parameter of a dispatching
operation shall be tag indeterminate.
If a dispatching operation is defined by a subprogram_renaming_declaration
or the instantiation of a generic subprogram, any access parameter of the
renamed subprogram or the generic subprogram that corresponds to a
controlling access parameter of the dispatching operation, shall be
null excluding.
!corrigendum 3.9.2(18)
Replace the paragraph:
- If the call has a controlling result and is itself a (possibly
parenthesized or qualified) controlling operand of an enclosing call on a
dispatching operation of type T, then its controlling tag value is
determined by the controlling tag value of this enclosing call;
by:
- If the call has a controlling result or controlling access result and
is itself, or designates, a (possibly parenthesized or qualified) controlling
operand of an enclosing call on a dispatching operation of a descendant of type
T, then its controlling tag value is determined by the controlling tag
value of this enclosing call;
- If the call has a controlling result or controlling access result and
(possibly parenthesized, qualified, or dereferenced) is the expression of an
assignment_statement whose target is of a class-wide type, then
its controlling tag value is determined by the target;
!corrigendum 3.10.2(07)
Replace the paragraph:
- An entity or view created by a declaration has the same accessibility
level as the innermost enclosing master, except in the cases of renaming and
derived access types described below. A parameter of a master has the same
accessibility level as the master.
by:
- An entity or view defined by a declaration and created as part of
its elaboration has the same accessibility
level as the innermost master of the declaration,
except in the cases of renaming and derived access types described below. A
parameter of a master has the same accessibility level as the master.
!corrigendum 3.10.2(09)
Replace the paragraph:
- The accessibility level of a view conversion is the same as that of
the operand.
by:
- The accessibility level of a view conversion, qualified_expression,
or parenthesized expression, is the same as that of the operand.
!corrigendum 3.10.2(10)
Replace the paragraph:
- For a function whose result type is a return-by-reference type, the
accessibility level of the result object is the same as that of the master that
elaborated the function body. For any other function, the accessibility level
of the result object is that of the execution of the called function.
by:
- The accessibility level of an aggregate or the result of a
function call (or equivalent use of an operator) that is used (in its entirety)
to directly initialize part of an object is that of the object being
initialized. In other contexts, the accessibility level of an aggregate or
the result of a function call is that of the innermost master that evaluates
aggregate or function call.
- Within a return statement, the accessibility level of the return
object is that of the execution of the return statement. If the
return statement completes normally by returning from the
function, then prior to leaving the function, the accessibility level
of the return object changes to be a level determined by the point
of call, as does the level of any coextensions (see below) of the
return object.
!comment !corrigendum 3.10.2(11)
!comment Since we want no change, we commented out the change in AI-385.
!comment @ddel This paragraph, added by AI95-00385, should be deleted.
!corrigendum 3.10.2(12)
Replace the paragraph:
- The accessibility level of the anonymous access type of an access
discriminant is the same as that of the containing object or associated
constrained subtype.
by:
- The accessibility level of the anonymous access type defined by an
access_definition of an object_renaming_declaration is the same as
that of the renamed view.
- The accessibility level of the anonymous access type of an access
discriminant in the subtype_indication or qualified_expression of an
allocator, or in the expression or return_subtype_indication of
a return statement is determined as follows:
- If the value of the access discriminant is determined by a
discriminant_association in a subtype_indication, the
accessibility level of the object or subprogram designated by
the associated value (or library level if the value is null);
- If the value of the access discriminant is determined by a
component_association in an aggregate, the accessibility
level of the object or subprogram designated by the associated
value (or library level if the value is null);
- In other cases, when the value of the access discriminant is
determined an object with an unconstrained
nominal subtype, the accessibility level of the object.
- The accessibility level of the anonymous access type of an access
discriminant in any other context is that of the enclosing object.
!corrigendum 3.10.2(13)
!comment A fake to force a conflict.
@ddel The second paragraph added by AI95-00318 should be deleted.
!corrigendum 3.10.2(14)
Replace the paragraph:
- The accessibility level of an object created by an allocator is
the same as that of the access type.
by:
- The accessibility level of an object created by an allocator is
the same as that of the access type, except for an allocator of an
anonymous access type that defines the value of an access parameter or
an access discriminant. For an allocator defining the value of
an access parameter, the accessibility level is that of the
innermost master of the call. For one defining an access
discriminant, the accessibility level is determined as follows:
- for an allocator used to define the constraint in a
subtype_declaration, the level of the subtype_declaration;
- for an allocator used to define the constraint in a
component_definition, the level of the enclosing type;
- for an allocator used to define the discriminant of an object,
the level of the object.
In this last case, the allocated object is said to be a
coextension of the object whose discriminant designates it, as well as of
any object of which the discriminated object is itself a coextension or
subcomponent. All coextensions of an object are finalized when the object is
finalized (see 7.6.1).
!corrigendum 3.10.2(16)
Insert after the paragraph:
- The accessibility level of a component, protected subprogram, or entry
of (a view of) a composite object is the same as that of (the view of) the
composite object.
the new paragraph:
In the above rules, the
operand of a view conversion, parenthesized expression or
qualified_expression is considered to be used in a context if the view
conversion, parenthesized expression or qualified_expression itself is
used in that context.
!corrigendum 04.08(05)
Insert after the paragraph:
If the type of the allocator is an access-to-constant type, the
allocator shall be an initialized allocator. If the designated type is
limited, the allocator shall be an uninitialized allocator.
the new paragraph:
If the designated subtype of the type of the allocator has one or
more unconstrained access discriminants, then the accessibility level
of the anonymous access type of each access discriminant, as
determined by the subtype_indication or qualified_expression of the
allocator, shall not be statically deeper than that of the type of
the allocator (see 3.10.2).
!corrigendum 04.08(10)
!comment This includes the AI-344 change.
@dinsa
@xbullet<If the designated type is composite, an object of the designated type
is created with tag, if any, determined by the @fa<subtype_mark> of the
@fa<subtype_indication>; any per-object constraints on subcomponents are
elaborated (see 3.8) and any implicit initial values for the subcomponents
of the object are obtained as determined by the @fa<subtype_indication>
and assigned to the corresponding subcomponents. A check is made that the
value of the object belongs to the designated subtype. Constraint_Error is
raised if this check fails. This check and the initialization of the object are
performed in an arbitrary order.>
@dinst
For any @fa<allocator>, if the
designated type of the type of the @fa<allocator> is class-wide, then
a check is made that the accessibility level of the type determined by
the @fa<subtype_indication>, or by the tag of the value of the
@fa<qualified_expression>, is not deeper than that
of the type of the @fa<allocator>. If the
designated subtype of the @fa<allocator> has one or more unconstrained
access discriminants, then a check is made that the accessibility
level of the anonymous access type of each access discriminant is
not deeper than that of the type of the @fa<allocator>.
Program_Error is raised if either such check fails.
!corrigendum 6.5(05)
Replace the paragraph:
A function body shall contain at least one return_statement that applies
to the function body, unless the function contains code_statements. A
return_statement shall include a return expression if and only if
it applies to a function body.
by:
A function body shall contain at least one return_statement that applies
to the function body, unless the function contains code_statements. A
simple_return_statement shall include an expression if and only if
it applies to a function body. An extended_return_statement shall apply to
a function body.
If the result subtype of a function is defined by a subtype_mark, the
return_subtype_indication of an extended_return_statement that
applies to the function body shall be a subtype_indication. The type of
the subtype_indication shall be the result type of the function. If the
result subtype of the function is constrained, then the subtype defined by the
subtype_indication shall also be constrained and shall statically match
this result subtype. If the result subtype of the function is unconstrained,
then the subtype defined by the subtype_indication shall be a definite
subtype, or there shall be an @nt{expression}.
If the result subtype of the function is defined by an access_definition,
the return_subtype_indication shall be an access_definition. The
subtype defined by the access_definition shall statically match the result
subtype of the function. The accessibility level of this anonymous access
subtype is that of the result subtype.
If the result subtype of the function is limited, then the expression
shall be an aggregate, a function call (or equivalent use of an operator),
or a qualified_expression or parenthesized expression whose operand is one
of these.
If the result subtype of the function is class-wide, the accessibility level of
the type of the expression of the return statement shall not be
statically deeper than that of the master that elaborated the function
body. If the result
subtype has one or more unconstrained access discriminants, the
accessibility level of the anonymous access type of each access discriminant,
as determined by the expression of the simple_return_statement or the
return_subtype_indication, shall not be statically deeper than that of the
master that elaborated the function body.
Static Semantics
Within an extended_return_statement, the return object is declared
with the given identifier, with the nominal subtype defined by the
return_subtype_indication.
!corrigendum 6.5(06)
Replace the paragraph:
For the execution of a return_statement, the expression (if any) is
first evaluated and converted to the result subtype.
by:
For the execution of an extended_return_statement, the
subtype_indication or access_definition is elaborated. This creates
the nominal subtype of the return object. If there is an expression,
it is evaluated and converted
to the nominal subtype (which might raise Constraint_Error — see 4.6); the
return object is created and the converted value
becomes the initial value of the return object; otherwise, the return object is
created and
initialized by default as for a stand-alone object of its nominal subtype
(see 3.3.1). If the nominal subtype is indefinite, the return object is
constrained by its initial value. The handled_sequence_of_statements, if
any, is then executed.
For the execution of a simple_return_statement, the expression
(if any) is first evaluated and converted to the result subtype to become
the value of the anonymous return object.
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).
!corrigendum 6.5(20)
Insert after the paragraph:
The exception Program_Error is raised if this check fails.
by:
If the result type is class-wide, a check is made that the
accessibility level of the type identified by the tag of the result
is not deeper than that of the master that elaborated the function
body. If the result subtype has one or more unconstrained access
discriminants, a check is made that the accessibility level of the
anonymous access type of each access discriminant, as determined by
the expression of the simple_return_statement or the
return_subtype_indication, is not deeper than that of the master that
elaborated the function body. If either check fails, Program_Error is raised.
!corrigendum 6.5(22)
Insert after the paragraph:
Finally, a transfer of control is performed which completes the
execution of the construct to which the return_statement applies,
and returns to the caller.
the new paragraph:
Implementation Permissions
If the result subtype of a function is unconstrained,
and a call on the function is used to provide the initial value of
an object with a constrained nominal subtype, Constraint_Error may
be raised at the point of the call (after abandoning the
execution of the function body) if, while elaborating the
return_subtype_indication or evaluating the expression of a return
statement that applies to the function body, it is determined that the value
of the result will violate the constraint of this object's subtype.
!corrigendum 7.6.1(03)
Replace the paragraph:
After execution of a construct or entity is complete, it is left, meaning
that execution continues with the next action, as defined for the execution
that is taking place. Leaving an execution happens immediately after its
completion, except in the case of a master: the execution of a task_body,
a block_statement, a subprogram_body, an entry_body, or an
accept_statement. A master is finalized after it is complete, and before
it is left.
by:
After execution of a construct or entity is complete, it is left, meaning
that execution continues with the next action, as defined for the execution
that is taking place. Leaving an execution happens immediately after its
completion, except in the case of a master: the execution of a body other than
a package_body; the execution of a statement; or
the evaluation of an expression, function_call, or range that is not part of an
enclosing expression, function_call, range, or simple_statement
other than a simple_return_statement.
A master is finalized after it is complete, and before it is left.
!corrigendum 7.6.1(09)
Replace the paragraph:
- If the object is of a composite type, then after performing the above
actions, if any, every component of the object is finalized in an arbitrary
order, except as follows: if the object has a component with an access
discriminant constrained by a per-object expression, this component is
finalized before any components that do not have such discriminants; for an
object with several components with such a discriminant, they are finalized in
the reverse of the order of their component_declarations.
by:
- If the object is of a composite type, then after performing the above
actions, if any, every component of the object is finalized in an arbitrary
order, except as follows: if the object has a component with an access
discriminant constrained by a per-object expression, this component is
finalized before any components that do not have such discriminants; for an
object with several components with such a discriminant, they are finalized in
the reverse of the order of their component_declarations;
- If the object has coextensions (see 3.10.2), each coextension is
finalized after the object whose access discriminant designates it.
!corrigendum 9.2(02)
Replace the paragraph:
A task object (which represents one task) can be created either as part of the
elaboration of an object_declaration occurring immediately within some
declarative region, or as part of the evaluation of an allocator. All
tasks created by the elaboration of object_declarations of a single
declarative region (including subcomponents of the declared objects) are
activated together. Similarly, all tasks created by the evaluation of a single
allocator are activated together. The activation of a task is associated
with the innermost allocator or object_declaration that is
responsible for its creation.
by:
A task object (which represents one task) can be a part of a
stand-alone object, of an object created by an allocator, or of an
anonymous object of a limited type, or a coextension of one of these.
All tasks that are part or coextensions of any
of the stand-alone objects created by the elaboration of
object_declarations (or generic_associations of formal objects of
mode in) of a single declarative region are activated together. All tasks
that are part or coextensions of a single object that is not a stand-alone
object are activated together.
!corrigendum 9.2(03)
Replace the paragraph:
For tasks created by the elaboration of object_declarations of a given
declarative region, the activations are initiated within the context of the
handled_sequence_of_statements (and its associated exception_handlers
if any — see 11.2), just prior to executing the statements of the
_sequence. For a package without an explicit body or an explicit
handled_sequence_of_statements, an implicit body or an implicit
null_statement is assumed, as defined in 7.2.
by:
For the tasks of a given declarative region, the activations are initiated
within the context of the handled_sequence_of_statements (and its
associated exception_handlers if any — see 11.2), just prior to executing
the statements of the handled_sequence_of_statements. For a package
without an explicit body or an explicit handled_sequence_of_statements, an
implicit body or an implicit null_statement is assumed, as defined in 7.2.
!corrigendum 9.2(04)
Replace the paragraph:
For tasks created by the evaluation of an allocator, the activations are
initiated as the last step of evaluating the allocator, after completing
any initialization for the object created by the allocator, and prior to
returning the new access value.
by:
For tasks that are part or coextensions of a single object that is not a
stand-alone object, activations are initiated after completing any
initialization of the outermost object enclosing these tasks, prior
to performing any other operation on the outermost object. In
particular, for tasks that are part or coextensions of the object created
by the evaluation of an allocator, the activations are initiated as
the last step of evaluating the allocator, prior
to returning the new access value. For tasks that are part or coextensions
of an object that is the result of a function call, the activations are
not initiated until after the function returns.
!corrigendum 9.3(3)
Insert after the paragraph:
- If the task is created by the elaboration of an
object_declaration, it depends on each master that includes this
elaboration.
the new paragraph:
- Otherwise, the task depends on the master of the
outermost object of which it is a part (as determined by the accessibililty
level of that object — see 3.10.2 and 7.6.1), as well as on any master
whose execution includes that of the master of the outermost object.
!corrigendum 13.11(25)
Replace the paragraph:
A storage pool for an anonymous access type should be created at the point of
an allocator for the type, and be reclaimed when the designated object becomes
inaccessible.
by:
The storage pool used for an allocator of an anonymous access type should
be determined as follows:
- If the allocator is defining a coextension (see 3.10.2) of an
object being created by an outer allocator, then the storage pool used
for the outer allocator should also be used for the coextension;
- Otherwise, the storage pool should be created at the point of the
allocator, and be reclaimed when the allocated object becomes
inaccessible.
!corrigendum 13.11.1(3)
Replace the paragraph:
Denotes the maximum value for Size_In_Storage_Elements that will be requested
via Allocate for an access type whose designated subtype is S. The value of
this attribute is of type universal_integer.
by:
Denotes the maximum value for Size_In_Storage_Elements that will be requested
via Allocate for an access type whose designated subtype is S.
For a type with access discriminants, if the implementation
allocates space for a coextension in the same pool as that
of the object having the access discriminant, then
this accounts for any calls on Allocate that could be
performed to provide space for such coextensions.
The value of this attribute is of type universal_integer.
!corrigendum 13.11.2(9)
Replace the paragraph:
- 3.
- Free(X), when X is not equal to null first performs
finalization, as described in 7.6. It then deallocates the storage
occupied by the object designated by X. If
the storage pool is a user-defined object, then the storage is
deallocated by calling Deallocate, passing
access_to_variable_subtype_name'Storage_Pool as the Pool
parameter. Storage_Address is the value returned in the
Storage_Address parameter of the corresponding Allocate call.
Size_In_Storage_Elements and Alignment are the same values passed
to the corresponding Allocate call. There is one exception: if the
object being freed contains tasks, the object might not be
deallocated.
by:
- 3.
- Free(X), when X is not equal to null first performs
finalization of the object designated by X (and any coextensions of the
object — see 3.10.2), as described in 7.6.1. It then deallocates the
storage occupied by the object designated by X (and any coextensions). If
the storage pool is a user-defined object, then the storage is
deallocated by calling Deallocate, passing
access_to_variable_subtype_name'Storage_Pool as the Pool
parameter. Storage_Address is the value returned in the
Storage_Address parameter of the corresponding Allocate call.
Size_In_Storage_Elements and Alignment are the same values passed
to the corresponding Allocate call. There is one exception: if the
object being freed contains tasks, the object might not be
deallocated.
!corrigendum 13.11.2(10)
Replace the paragraph:
After Free(X), the object designated by X, and any subcomponents
thereof, no longer exist; their storage can be reused
for other purposes.
by:
After Free(X), the object designated by X, and any subcomponents (and
coextensions) thereof, no longer exist; their storage can be reused
for other purposes.
!comment !corrigendum 13.11.2(17)
!comment This just removes the change made by AI-00416. It is removed
!comment there, and nothing need be done here.
!ACATS test
Create C-Tests to check that controlling access results dispatch properly.
!appendix
!topic Accessibility level--contradiction?
!reference RM05 3.10.2, 7.6.1
!from Adam Beneschan 05-02-09
!discussion
I'm trying to understand how accessibility levels work with the new
generalized anonymous access type stuff, and I'm running into some
difficulties. If my understanding of the RM is correct (a dubious
assumption), it appears that the RM is saying something
self-contradictory.
Consider this example:
procedure P1 is
type Rec is record
C1 : access Integer;
end record;
begin...end P1;
As I understand it, the elaboration of Rec is now considered to be a
master, which has an accessibility level. The type Rec also has an
accessibility level (3.10.2(7)). Of course, the execution of P1 is a
master that has an accessibility level. I'll denote these as
Level(Elaboration-of-Rec), Level(Rec), and Level(P1), and use ">" to
mean "deeper than".
According to 3.10.2(7), an entity created by a declaration has the
same accessibility level as the innermost enclosing master other than
the declaration itself. The type Rec is an entity. It seems clear
that the innermost enclosing master for this type declaration is the
execution of P1. Thus, Level(Rec) = Level(P1).
3.10.2(12/2) says, "The accessibility level of the anonymous access
type of a component is that of the master that elaborated its
access_definition. This is the same as the level of the type whose
definition encloses the access_definition except in the case of an
access discriminant....." Thus, the level of the anonymous access
type "access Integer" is that of the master that elaborated this
access definition. If we follow 3.8(16-17), we find that the
elaboration of Rec, which is a master, contains the elaboration of the
record_definition, which contains the elaboration of the
component_list, which contains the elaboration of the component_items
(including component_declarations), which contain the elaboration of
the component_definition, which is the access_definition in this case.
Thus, the master that elaborated the access definition is the
elaboration of Rec. This means that, according to this paragraph, the
accessibility level of the elaboration of this master,
i.e. Level(Elaboration-of-Rec), is the same as the level of the type
whose definition encloses the access definition, i.e. Level(Rec).
[And the level of the anonymous access type is the same as both.]
Thus, we have Level(Elaboration-of-Rec) = Level(Rec).
Since we already established that Level(Rec) = Level(P1), this means
Level(Elaboration-of-Rec) = Level(P1).
3.10.2(6) says that the accessibility level of a master is deeper than
that of each dynamically enclosing master. Since the execution of P1
dynamically encloses the elaboration of Rec, which is a master, we
therefore have Level(Elaboration-of-Rec) > Level(P1).
Something's wrong.
*************************************************************
From: Tucker Taft
Sent: Wednesday, February 9, 2005 7:54 PM
I think you are right. 3.10.2(7/2) says the following:
An entity or view created by a declaration has the same
accessibility level as the innermost enclosing master other
than the declaration itself except in the cases of renaming
and derived access types described below. A parameter of a
master has the same accessibility level as the master.
and 7.6.1(3/2) says:
... a master: the execution of a body other than a package_body;
the elaboration of a declaration other than the declaration of a
package; the execution of an accept_statement, a block_statement,
or a simple_statement; or the evaluation of an expression or range
that is not part of an enclosing expression, range, or
simple_statement.
Although "access_definition" is not a declaration,
"component_declaration" and "type_declaration" are
both declarations, and we really only want one
level there. So 7.6.1 should probably exempt type
declarations as well as package declarations from
being masters. I think that would solve the problem
you identify. Like package declarations, type
declarations are essentially "see-through." Of course
entities created as part of the creation of an *object* of
the type are another matter, and those are clearly related
to the accessibility of the object, not the
type declaration.
> Consider this example:
>
> procedure P1 is
>
> type Rec is record
> C1 : access Integer;
> end record;
>
> begin...end P1;
> ...
If we eliminate "Rec" as a master, then the master
of the anonymous access type created by the
elaboration of "C1" is now P1, rather than Rec.
Which is what we want.
*************************************************************
From: Tucker Taft
Sent: Thursday, February 17, 2005 3:17 AM
Our last discussion about access discriminants
and allocators in Paris was a bit concerning,
I'm sure. For what it's worth, I believe I have
worked out all the problems, and the "joined at
the hip" model will work for nonlimited types
as well. Generally, the solution is to return
more closely to the rule that an access discriminant
always has the same level as the object it is
a component of. I had broken that rule for objects
returned by functions when referring to an
access discriminant of a subcomponent of the
result, and that was causing the trouble, I
believe. Calling a function and then only using
a part of the result is quite rare, and using
a part that happens to have an access discriminant
that is initialized from the enclosing object's
access discriminant is well below the noise
level.
Overall, the general rule becomes that as soon
as you select a component of a function result,
the function result is treated as a "temp",
and it takes on a very local accessibility
level, as do any access discriminants it has.
E.g.:
X : T := func().component;
is not permitted if component has an access
discrim. initialized from the enclosing object,
because the call is a temp, and we are
trying to initialize a longer-lasting
object. Another way to think about it is
that only when "build-in-place" is possible
can the result of the function call be
long-lived.
I'll write all this up in the next version of
the AI.
So those who were concerned can breathe easier. ;-)
*************************************************************
From: Jean-Pierre Rosen
Sent: Wednesday, November 30, 2005 4:22 AM
Unless I missed something...
9.3 (3) talks about task created by the elaboration of an object
declaration. But the identifer of an extended return is not an object
declaration. Moreover, we don't want the master to be the function; it
should be the *caller* of the function (i.e. the place where the "return
object" is created).
*************************************************************
From: Randy Brukardt
Sent: Wednesday, November 30, 2005 8:26 AM
> Unless I missed something...
You did. I hope. :-)
> 9.3 (3) talks about task created by the elaboration of an object
> declaration. But the identifer of an extended return is not an object
> declaration. Moreover, we don't want the master to be the function; it
> should be the *caller* of the function (i.e. the place where the "return
> object" is created).
The master is determined by the accessibility level in general (see 3.10.2).
3.10.2(10.1) describes the accessibility level for return objects. The
intent is clearly that this determines when finalization and task waiting
occurs (see 6.5(5.e-5.f) for instance).
In any case, for a limited type, the return object is really a view of the
ultimate result. The tasks are created directly in this ultimate result.
(This is required by 7.5(9.1)). The ultimate result has to be an allocator
or an object_declaration (other uses of limited expressions are illegal), so
I think the master is defined. (If the return object is never returned, the
tasks are never activated, so they don't need to be waited for or even have
a master.)
Admittedly, this is a bit hand-wavey, but it seems like a lot of wording
would need changes otherwise, and I'd rather avoid that at this late date.
Perhaps we should add an AARM note somewhere, but what would it say??
*************************************************************
From: Jean-Pierre Rosen
Sent: Thursday, December 1, 2005 3:11 AM
> The master is determined by the accessibility level in general (see 3.10.2).
> 3.10.2(10.1) describes the accessibility level for return objects. The
> intent is clearly that this determines when finalization and task waiting
> occurs (see 6.5(5.e-5.f) for instance).
>
There is no doubt about the intent, but this justification is a bit
far-reaching (we are talking about access types here)...
You say that "The master *is determined* by the accessibility level",
but the RM says "Each master, and each entity and view created by it,
*has* an accessibility level". I don't think that the RM says that the
master of an entity is the construct that corresponds to its
accessibility level.
The place that defines what is the master of a task is clearly 9.3. Why
not add a third bullet after 9.3(3) that says the truth:
If the task is created by the elaboration of the return object of an
extended_return_statement, the master is the function to which the
extended_return_statement applies until the function returns; when
the function returns, the master is changed to be the master that
elaborated the declaration for which this function call is the
initialization expression.
AARM note:
Other rules ensure that a function that returns a task can be used
only as the initialization expression of an object declaration.
*************************************************************
From: Pascal Leroy
Sent: Thursday, December 1, 2005 4:07 AM
> You say that "The master *is determined* by the accessibility level",
> but the RM says "Each master, and each entity and view created by it,
> *has* an accessibility level". I don't think that the RM says
> that the
> master of an entity is the construct that corresponds to its
> accessibility level.
It does, in 7.6.1(13), this is the rule that ties masters to accessibility
levels and makes it possible to define the dependence/finalization rules
by "simply" specifying accessibility levels.
> Why not add a third bullet after 9.3(3) that says the truth:
>
> If the task is created by the elaboration of the return object of an
> extended_return_statement, the master is the function to which the
> extended_return_statement applies until the function returns; when
> the function returns, the master is changed to be the master that
> elaborated the declaration for which this function call is the
> initialization expression.
This would be redundant with 3.10.2(10.1), and we certainly don't want to
introduce redundancy in the accessibility rules, they are complicated
enough as they stand. Furthermore, the above doesn't work: it doesn't
address simple_return_statements, finalization of controlled types,
coextensions, and function calls that are being renamed.
I agree that 9.3(2-3) are a bit bogus because there are other ways to
create tasks than allocators and object_declarations, but if we absolutely
wanted to fix them, the best option would be to delete them altogether and
depend on the accessibility rules.
But that seems insufficiently broken to me. Maybe an AARM note saying
"there are other ways to create tasks, go read 3.10.2" would help.
*************************************************************
From: Jean-Pierre Rosen
Sent: Thursday, December 1, 2005 3:11 AM
> I agree that 9.3(2-3) are a bit bogus because there are other ways to
> create tasks than allocators and object_declarations, but if we absolutely
> wanted to fix them, the best option would be to delete them altogether and
> depend on the accessibility rules.
>
> But that seems insufficiently broken to me. Maybe an AARM note saying
> "there are other ways to create tasks, go read 3.10.2" would help.
And a "to be honnest": masters of a task are not really defined here,
but in 7.6.1(13).
*************************************************************
From: Tucker Taft
Sent: Thursday, December 1, 2005 12:22 PM
In looking at 9.2(2-3) and 9.3(2-3) together, it is a bit
weird that 9.2 talks carefully about all kinds of task objects,
but 9.3 blithely only talks about tasks created by allocators
or object declarations. It would seem fairly straightforward to
adapt the wording of 9.2(2-3) for 9.3(2-3), so these two
sections are consistent.
*************************************************************
From: Randy Brukardt
Sent: Thursday, December 1, 2005 2:53 PM
If you're suggesting this as an exercise for the editor, thanks, but I'll
pass. A quick look at 9.2(2-3) shows an incredibly messy bunch of lists and
conditions. How that maps to 9.3(2-3) is not at all clear to me.
For now, I'll add some AARM notes as suggested, and if someone wants to take
a stab at fixing the wording and submitting it through one of the WG9
channels, please go ahead.
*************************************************************
From: Tucker Taft
Sent: Thursday, December 1, 2005 3:51 PM
OK. How does this sound?
What exactly are the right channels for submission,
by the way?
-------------
Existing 9.3(2-3):
* If the task is created by the evaluation of an allocator
for a given access type, it depends on each master that
includes the elaboration of the declaration of the ultimate
ancestor of the given access type.
* If the task is created by the elaboration of an
object_declaration, it depends on each master that includes
this elaboration.
Add the following after the above:
* Otherwise, the master of the task is determined by the
master of the outermost object of which it is a part, as
determined by the accessibililty level of that object (see
3.10.2 and 7.6.1).
AARM NOTE: The master of a task created by a return
statement changes when the accessibility of the return
object changes. Note that its activation happens, if at
all, only after the function returns and all
accessibility level changes have occurred.
*************************************************************
From: Randy Brukardt
Sent: Thursday, December 1, 2005 4:16 PM
> OK. How does this sound?
Looks OK to me, although it doesn't seem very similar to 9.2(2-3). (I don't
care about that much anyway.)
> What exactly are the right channels for submission, by the way?
We're still working that out, but it would have to be via a
head-of-delegation or liaison. In your case, either Joyce Tokar (US) or John
McCormick (SIGAda).
I'll try to make the rules clear when I post the next set of drafts. But I
gotta finish them first...
*************************************************************
From: Pascal Leroy
Sent: Thursday, December 1, 2005 4:55 PM
> What exactly are the right channels for submission,
> by the way?
I want Randy to focus on draft 15 at this point, so that we can send it to
WG9 for review, hopefully next week.
To avoid confusion or arguments, draft 15 should exactly reflect what was
decided at the last ARG meeting, not more, not less. Otherwise we run the
risk of indefinite postponement, and someone could well argue that we are
bending the rules.
As you know, once draft 15 has been sent to WG9, there will be a review
period ending around January 31st. Comments should be submitted to
National Bodies or Liaison Organizations, who will forward them to AXE
Consulting (aka Dr. Randy). I think we want to be fairly formal in
conducting this review, so there is no reason to have a special permission
for the ARG members to submit comments directly. Like the general public,
they should go through NBs or LOs. After all, it should not be too hard
for ARG members to convince their favorite HoD to submit an official
comment.
*************************************************************
From: Dan Eilers
Sent: Friday, December 1, 2005 11:51 AM
> I think we want to be fairly formal in
> conducting this review, so there is no reason to have a special permission
> for the ARG members to submit comments directly.
This seems to be mistaken. "We" as in "the Arg" aren't conducting this
review--it's a WG9 review. The WG9 minutes for meeting #48 say:
# T through T+30: Informal review by member bodies and "socialization"
# to the public, resulting in minor comments.
So it appears that the intent of WG9 is for this to be an _informal_ review.
And it appears that the intent is to receive comments both from member
bodies and the public, with no mention that the public comments should go
through the member bodies as opposed to the normal channels for public
comments.
> To avoid confusion or arguments, draft 15 should exactly reflect what was
> decided at the last ARG meeting, not more, not less. Otherwise we run the
> risk of indefinite postponement, and someone could well argue that we are
> bending the rules.
The WG9 minutes for meeting #49 say:
# If the amendment completes its current review in the ARG without
# comments requiring substantial remark then it should be possible for
# the ARG to make an informational distribution in early December.
Since this is only an "informational" distribution, there doesn't seem
to be any reason to be overly concerned about "bending the rules",
since there aren't really any rules for "informational" distributions.
I am sympathetic to the concern about indefinite postponement, but the
Rationale isn't available yet, and it will hardly be possible to conduct
a meaningful review of the Amendment without the Rationale showing how
the new features are intended to be be used, what AI's were discussed
but not incorporated, and what incompatibilities were introduced.
*************************************************************
From: Pascal Leroy
Sent: Saturday, December 3, 2005 6:46 AM
...
> So it appears that the intent of WG9 is for this to be an
> _informal_ review. And it appears that the intent is to
> receive comments both from member bodies and the public, with
> no mention that the public comments should go through the
> member bodies as opposed to the normal channels for public comments.
If you look at the draft minutes for meeting #49 you will find a sentence
that says: 'The process is long past the stage when the ARG would accept
comments from the "public"'. The discussion at the meeting made it clear
that WG9 wanted comments to be channeled through HoDs. I expect this to
be reflected in the final minutes.
...
> Since this is only an "informational" distribution, there
> doesn't seem to be any reason to be overly concerned about
> "bending the rules", since there aren't really any rules for
> "informational" distributions.
NBs and LOs may well have their own rules for conducting this kind of
review, even though it's informal from the perspective of WG9. I don't
want to give anyone the impression that the ARG has somehow the privilege
of short-circuiting these rules. This may be overly cautious, but better
safe than sorry. The last thing I want at this stage is to ruffle
feathers.
> I am sympathetic to the concern about indefinite
> postponement, but the Rationale isn't available yet, and it
> will hardly be possible to conduct a meaningful review of the
> Amendment without the Rationale showing how the new features
> are intended to be be used, what AI's were discussed but not
> incorporated, and what incompatibilities were introduced.
Remember that the Rationale is not a deliverable of the ISO amendment
process, and while I agree that it helps in understanding the new features
of the language, I am sure that a "meaningful review" of the Amendment can
be done (and has been done over the last year) without looking at the
Rationale. In particular, the Rationale is not at a level of detail
sufficient to analyze the correctness of most of the individual rules.
*************************************************************
From: Erhard Ploedereder
Sent: Sunday, December 4, 2005 9:34 AM
> So it appears that the intent of WG9 is for this to be an _informal_
> review.
Putting on my WG9 HOD hat:
The intent of the WG9 review is to informally solicit those comments from
the country delegations that they would make if this draft version were
officially submitted at this point. The intent is further that all such
comments be made at this time and that no new issues be raised later about
the officially submitted draft (and that this draft obviously addresses
issues raised in the inofficial round). It is therefore important that all
comments on the draft 15 be channeled through WG9. The only way to do so is
via the heads of delegation.
*************************************************************
Questions? Ask the ACAA Technical Agent