Version 1.13 of ais/ai-00127.txt
!standard 03.09.02 (07) 00-07-31 AI95-00127/10
!standard 03.09.02 (09)
!standard 03.10.02 (24)
!standard 03.10.02 (27)
!standard 04.08 (03)
!class binding interpretation 96-04-04
!status Corrigendum 2000 99-05-25
!status WG9 approved 96-12-07
!status ARG approved 8-0-4 96-10-07
!status ARG approved (subj. ed. rev., letter ballot was 9-0-2) 96-10-03
!status ARG approved 7-0-1 (subject to letter ballot) 96-06-17
!status work item 96-04-04
!status received 96-04-04
!priority High
!difficulty Medium
!qualifier Error
!subject Expected type of a 'Access attribute
!summary
An attribute reference of the Access attribute may be used as the actual
parameter in a dispatching call, if the formal is an access parameter
designating a tagged type, and the prefix of the attribute reference is
of the corresponding class-wide type. Such an actual is considered to
be dynamically tagged.
An analogous rule applies to an attribute reference of Unchecked_Access
and to an allocator.
!question
Consider the following code fragment:
<<Start_Example>>
type T is tagged null record;
procedure P(X : access T);
Y : aliased T'Class := ...;
type T_Ptr is access all T'Class;
Z : T_Ptr;
P(Y'Access); -- (1) Legal? (Yes.)
P(new T'Class'(...)); -- (2) Legal? (Yes.)
P(Z); -- (3) Legal.
The call at (3) is clearly legal, and is a dispatching call.
However, the call at (1) appears to be illegal. The expected type for
Y'Access is the anonymous type "access T", by 6.4.1(3). 3.10.2(24)
says, "If the designated type of A [here, A is the anonymous access
type] is tagged, then the type of the view [Y] shall be covered by the
designated type". The type of the view is T'Class, which is not covered
by the designated type, which is T. Therefore, Y'Access is illegal
here.
The call at (2) appears to be illegal for the same reason.
It would seem that the same rules should apply to all of these calls;
(1) and (2) should be legal, and should be dispatching calls.
!recommendation
(See summary.)
!wording
In the last sentence of 3.10.2(24), give a name to the designated type,
so we can refer to it more easily in 3.10.2(27):
The view denoted by the prefix X shall satisfy the following
additional requirements, presuming the expected type for X'Access is
the general access type A{, with designated type D}:
Replace 3.10.2(27) with:
If A is a named access type and D is a tagged type, then the type of
the view shall be covered by D;
if A is anonymous and D is tagged, then the type of the view shall be
either D'Class or a type covered by D;
if D is untagged, then the type of the view shall be D, and A's designated
subtype shall either statically match the nominal subtype of the view or
be discriminated and unconstrained;
Modify 4.8(3) in a manner analogous to 3.10.2:
The expected type for an allocator shall be a single
access-to-object type with designated type D such that either D
covers the type determined by the subtype_mark of the
subtype_indication or qualified_expression, or the expected
type is anonymous and the determined type is D'Class.
Modify 3.9.2(7) to deal with Access attributes and allocators:
A type_conversion is statically or dynamically tagged according to
whether the type determined by the subtype_mark is specific or
class-wide, respectively. For an object that is designated by an
expression where the expected type is an anonymous access-to-specific
tagged type, the object is dynamically tagged if the expression,
ignoring enclosing parentheses, is of the form X'Access, where X is
of a class-wide type, or is of the form new T'(...), where T denotes
a class-wide subtype. Otherwise, the object is static or dynamically
tagged according to whether the designated type of the type of the
expression is specific or class-wide, respectively.
Correct 3.9.2(9) for the new definitions of dynamic taggedness:
If the expected type for an expression or name is some specific tagged
type, then the expression or name shall not be dynamically tagged unless
it is a controlling operand in a call on a dispatching operation.
Similarly, if the expected type for an expression is an anonymous
access-to-specific tagged type, then the object designated by the
expression shall not be dynamically tagged unless it designates a
controlling operand in a call on a dispatching operation.
!discussion
The rules should be equivalent in these cases; anything else would be
surprising to the programmer. This is achieved by the above wording.
In the call at (1), Y'Access is of the anonymous type "access T".
Y'Access is dynamically tagged, despite the fact that its type's
designated type is not class-wide.
In the call at (2), new T'Class'(...) is also of the anonymous type
"access T", and is also dynamically tagged.
Thus, all three calls are legal, and are dispatching calls to P.
No wording changes are needed for Unchecked_Access, since it is already
defined in terms of Access.
!corrigendum 3.09.02(7)
Replace the paragraph:
A type_conversion is statically or dynamically tagged according to whether
the type determined by the subtype_mark is specific or class-wide,
respectively. For a controlling operand that is designated by an actual
parameter, the controlling operand is statically or dynamically tagged
according to whether the designated type of the actual parameter is specific
or class-wide, respectively.
by:
A type_conversion is statically or dynamically tagged according to whether
the type determined by the subtype_mark is specific or class-wide,
respectively. For an object that is designated by an expression whose
expected type is an anonymous access-to-specific tagged type, the object
is dynamically tagged if the expression, ignoring enclosing parentheses, is
of the form X'Access, where X is of a class-wide type, or is of the form
new T'(...), where T denotes a class-wide subtype. Otherwise, the object is
statically or dynamically tagged according to whether the designated type of
the type of the expression is specific or class-wide, respectively.
!corrigendum 3.09.02(9)
Replace the paragraph:
If the expected type for an expression or name is some specific tagged
type, then the expression or name shall not be dynamically tagged unless it
is a controlling operand in a call on a dispatching operation. Similarly, if
the expected type for an expression is an anonymous access-to-specific tagged
type, then the expression shall not be of an access-to-class-wide type unless
it designates a controlling operand in a call on a dispatching operation.
by:
If the expected type for an expression or name is some specific tagged
type, then the expression or name shall not be dynamically tagged unless
it is a controlling operand in a call on a dispatching operation.
Similarly, if the expected type for an expression is an anonymous
access-to-specific tagged type, then the object designated by the expression
shall not be dynamically tagged unless it is a controlling operand in
a call on a dispatching operation.
!corrigendum 3.10.02(24)
Replace the paragraph:
- X'Access
-
X'Access yields an access value that designates the object
denoted by X. The type of X'Access is an access-to-object
type, as determined by the expected type. The expected type
shall be a general access type. X shall denote an aliased
view of an object, including possibly the current instance
(see 8.6) of a limited type within its definition, or a
formal parameter or generic formal object of a tagged type.
The view denoted by the prefix X shall satisfy the following
additional requirements, presuming the expected type for
X'Access is the general access type A:
by:
- X'Access
-
X'Access yields an access value that designates the object
denoted by X. The type of X'Access is an access-to-object
type, as determined by the expected type. The expected type
shall be a general access type. X shall denote an aliased
view of an object, including possibly the current instance
(see 8.6) of a limited type within its definition, or a
formal parameter or generic formal object of a tagged type.
The view denoted by the prefix X shall satisfy the following
additional requirements, presuming the expected type for
X'Access is the general access type A, with designated type D:
!corrigendum 3.10.02(27)
Replace the paragraph:
- If the designated type of A is tagged, then the type of the view
shall be covered by the designated type; if A's designated type is not
tagged, then the type of the view shall be the same, and either A's
designated subtype shall statically match the nominal subtype of the view,
or the designated subtype shall be discriminated and unconstrained;
by:
- If A is a named access type and D is a tagged type, then the
type of the view shall be covered by D; if A is anonymous and D is
tagged, then the type of the view shall be either D'Class or a type
covered by D; if D is untagged, then the type of the view shall be
D, and A's designated subtype shall either statically match the
nominal subtype of the view or be discriminated and unconstrained;
!corrigendum 4.08(03)
Replace the paragraph:
The expected type for an allocator shall be a single access-to-object
type whose designated type covers the type determined by the subtype_mark
of the subtype_indication or qualified_expression.
by:
The expected type for an allocator shall be a single access-to-object type with
designated type D such that either D covers the type determined by the
subtype_mark of the subtype_indication or qualified_expression,
or the expected type is anonymous and the determined type is D'Class.
!ACATS test
Test C392012 checks that objects designated by X'Access (where X is of a
class-wide type) and new T'() where T is a class-wide type are dynamically
tagged and support dispatching. (Test, 7-1-0, ARG Letter Ballot, February 2001).
!appendix
!section 3.10.2(27)
!subject Expected type of a 'Access attribute
!reference RM95-3.10.2(27)
!from Pascal Leroy 96-03-12
!reference 96-5444.a Pascal Leroy 96-3-13>>
!discussion
Consider the following code fragment:
type T is tagged null record;
procedure P (X : access T);
Y : aliased T'Class := ...;
P (Y'Access);
Is the usage of 'Access in the procedure call legal?
RM95 6.4.1(3) says that "the expected type for an actual parameter is the type
of the corresponding formal parameter." Thus, the expected type for Y'Access
is the anonymous access type "access T".
Now the legality of the 'Access attribute. RM95 3.10.2(24-28) expresses a
number of rules that apply to the prefix of the attribute: "The view denoted
by the prefix shall satisfy the following requirements, presuming the expected
type ... is the general access type A" (RM95 3.10.2(24)). In our case, the
expected type is the anonymous access type "access T" as explained above.
One of the requirements applicable to the prefix is stated by RM95 3.10.2(27):
"If the designated type of A is tagged, then the type of the view shall be
covered by the designated type". Here the designated type of the anonymous
access type is T, which is tagged. But the type of the view is T'Class, which
is definitely not covered by T.
Following this line of reasoning, the expression Y'Access above would seem
illegal. But if that is the case, then how are we supposed to use access
parameters for dispatching?
_____________________________________________________________________
Pascal Leroy +33.1.30.12.09.68
pleroy@rational.com +33.1.30.12.09.66 FAX
****************************************************************
!section 3.10.2(27)
!subject Expected type of a 'Access attribute
!reference RM95-3.10.2(27)
!reference RM95-3.9.2(7,9)
!reference RM95-8.6(25)
!reference 96-5444.a Pascal Leroy 96-03-12
!from Tucker Taft 93-03-14
!reference 96-5445.a Tucker Taft 96-3-14>>
!discussion
> Consider the following code fragment:
>
> type T is tagged null record;
> procedure P (X : access T);
> Y : aliased T'Class := ...;
>
> P (Y'Access);
>
> Is the usage of 'Access in the procedure call legal?
>
> ...
> One of the requirements applicable to the prefix is stated by RM95 3.10.2(27):
> "If the designated type of A is tagged, then the type of the view shall be
> covered by the designated type". Here the designated type of the anonymous
> access type is T, which is tagged. But the type of the view is T'Class, which
> is definitely not covered by T.
I agree. This seems like a possible bug in the RM. If instead of Y'Access,
you had a value of a named access-to-T'Class type, it would be legal
by 8.6(25):
[the type of the construct shall resolve to T, or], when T
is an anonymous access type with designated type D, to an access-
to-variable type whose designated type is D'Class or is covered by D.
and 3.9.2(9):
... Similarly, if the expected type for an expression is an anonymous
access-to-specific tagged type, then the expression shall not be of an
access-to-class-wide type unless it designates a controlling operand
in a dispatching operation.
So it makes sense that any access-to-T'Class value should be allowed
as an actual parameter, as part of a dispatching call. The only
problem is that we don't really have a type for this value. In some
sense, we don't really need one, since it is about to be implicitly
converted to the anonymous access type, but it is a little awkward
to talk about Y'Access without being able to point to some type
declaration for it.
An alternative, and probably better, way of dealing with this would
be to say the type of Y'Access *is* the anonymous access-to-specific type
of the formal access parameter "X", but add a rule to 3.9.2(7)
defining <class_wide_obj>'Access to be a dynamically tagged operand,
even though its type (as determined by the expected type)
is in fact access-to-specific, and change 3.9.2(9) to disallow this
use unless it is in a call on a dispatching operation, and finally
allowing in 3.10.2(27) that the prefix can be of type A'Class in
addition to being a type covered by A.
The net effect of these changes would be to make the rules
governing an actual "blah'Access" matching a formal of type "access T"
equivalent to the rules coverning an actual "blah" matching a formal
of type "T". Gaining this equivalence seems like a good thing.
> Following this line of reasoning, the expression Y'Access above would seem
> illegal. But if that is the case, then how are we supposed to use access
> parameters for dispatching?
They work fine so long as the actual parameter is of a named access-to-
classwide type. The problem is only with <classwide_obj>'Access.
I agree that it would be nice to fix this problem.
> Pascal Leroy +33.1.30.12.09.68
> pleroy@rational.com +33.1.30.12.09.66 FAX
-Tuck
****************************************************************
From: Randy Brukardt, October 7, 1999
The text changes mentioned in my notes from the recent ARG meeting
for paragraphs 3.9.2(7) and 3.9.2(9) don't make sense in English. I've made
what I think are minimal corrections to the text. Here is what my original
notes say:
3.9.2(7)
Replace all but the first sentence:
For an object that is designated by an expression where the expected type is an
anonymous access-to-specific tagged type is dynamically tagged if the
expression, ignoring enclosing parentheses, is of the form X'Access, where X is
of a class-wide type, or is of the form new T'(...), where T denotes a class-wide
subtype. Otherwise, the object is staic or dynamically tagged according to
whether the designated type of the type of the expression is specific or
class-wide, respectively.
-- The first clause here makes no sense as written.
This paragraph was changed because:
-- Expressions are dynamically or statically tagged, not parameters per se;
-- We need this to apply to all expressions so 3.9.2(9) works;
-- A parenthesized expression should be either dynamically or statically
tagged depending on the contents.
3.9.2(9)
Replace:
...then the object designated by the expression shall not be dynamically tagged
unless it is designated...
-- "it is designated" doesn't match the following text "...a controlling operand...".
****************************************************************
From: Randy Brukardt, January 19, 2000
The (belated) minutes of the meeting make it clear what was intended here, and
this now has been done.
****************************************************************
Questions? Ask the ACAA Technical Agent