Version 1.4 of ais/ai-00127.txt

Unformatted version of ais/ai-00127.txt version 1.4
Other versions for file ais/ai-00127.txt

!standard 03.10.02 (27)          99-06-25 AI95-00127/05
!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
!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:
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 named and D is tagged, 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 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;
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 whose designated type covers the type determined by the subtype_mark of the subtype_indication or qualified_expression, {or, if the expected type is anonymous, whose designated type is the class-wide type corresponding to the determined type}.
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. {A controlling operand of the form X'Access, where X is of a class-wide type, is dynamically tagged. Similarly, a controlling operand of the form new T'(...), where T denotes a class-wide subtype, is dynamically tagged. For any other} 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.
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 expression shall not be [of an access-to-class-wide type]{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. A controlling operand of the form X'Access, where X is of a class-wide type, is dynamically tagged. Similarly, a controlling operand of the form new T'(...), where T denotes a class-wide subtype, is dynamically tagged. For any other 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.
!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 expression shall not be dynamically tagged unless it designates 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:
by:
!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 whose designated type covers the type determined by the subtype_mark of the subtype_indication or qualified_expression, or, if the expected type is anonymous, whose designated type is the class-wide type corresponding to the determined type.
!ACATS test
A C-Test is needed to check that the examples in the question are supported. Additional checks may be required to cover all of the wording changes.
!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

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

Questions? Ask the ACAA Technical Agent