Version 1.1 of ai05s/ai05-0284-1.txt
!standard 3.10.2(13/2) 12-01-04 AI05-0284-1/01
!class binding interpretation 11-11-13
!status work item 11-11-13
!status received 11-08-07
!priority Low
!difficulty Medium
!qualifier Omission
!subject Accessibility of anonymous access returns
!summary
!question
(1) In almost all cases, we have pairs of Legality and runtime rules for
accessibility checks. We don't have a Legality Rule for the accessibility checks
associated with anonymous access types.
function Bad return access Some_Type is
Local : aliased Some_Type;
begin
return Local'access; --
end Bad;
The above appears to require a runtime check raising Program_Error, as there is
no static level defined for the return object and thus we cannot apply
3.10.2(28/3). Only 3.10.2(29) can apply. Should this be changed?? (Dunno.)
(2) While 3.10.2 defines the accessibility level of an object of an anonymous
access function return, it does not define the accessibility level of the
associated type. There are a number of places where the accessibility level of
an access type is used, so this ought to be well-defined. Should this be fixed?
(Yes.)
!recommendation
(See summary.)
!wording
** TBD for (1).
For (2), add a top-level bulleted before 3.10.2(10.7/3):
In the case of a call to a function whose result type is an anonymous
access type, the accessibility level of the type of the result of
the function call is also determined by the point of call as described
above.
!discussion
Editor's ramblings: For (1), there doesn't seem to be any necessity of a static
rule (although it might cause implementation difficulties as outlined in
AI12-0016-1). But at least conceptually, the check is always possible at
runtime. I suspect that the static rule was omitted thinking that this is
similar for access parameters (which have no static rule), but the example in
the question shows this is not true. If we do adopt a static rule, it had better
allow the examples given in the !example section.
For (2), Steve points out that there is only one reasonable interpretation that
makes sense. But the wording doesn't support that interpretation directly. Thus
we ought to fix the wording.
!example
For question 1, any rule that we adopt should not make the following illegal:
type Named is access all Some_Type;
Ptr : Named;
procedure Proc is
function Fff return access Some_Type is ... ;
begin
Ptr := Named (Fff); --
end Proc;
For question 2, we want the following to compile and execute properly:
procedure Test is
subtype Designated is Integer;
type Global_Ref is access all Designated;
Global_Ptr : Global_Ref;
procedure Nested is
type Local_Ref is access all Designated;
Local_Ptr : Local_Ref;
function Func (Is_Local : Boolean) return access Designated is
begin
return Result : access Designated do
if (Result in Global_Ref) = Is_Local then
raise Program_Error;
end if;
declare
Sao : access Designated := Result;
begin
if (Sao in Global_Ref) = Is_Local then
raise Program_Error;
end if;
end;
end return;
end Func;
begin
Local_Ptr := Local_Ref (Func (Is_Local => True));
Global_Ptr := Global_Ref (Func (Is_Local => False));
end Nested;
begin
Nested;
end Test;
!ACATS Test
An ACATS C-Test should be created out of the example.
!appendix
From: Steve Baird
Sent: Monday, August 9, 2011 4:14 PM
3.10.2 includes
The statically deeper relationship does not apply to the
accessibility level of the type of a stand-alone object of
an anonymous access-to-object type;
and 4.6 has
If the target type is that of such a stand-alone object, the
accessibility level of the operand type shall not be statically
deeper than that of the declaration of the stand-alone object
Do we need analogous legality rules for an anonymous access function result type?
The idea is that the accessibility level is determined by the point of call, so
we want to allow something like
type Named is access all Some_Type;
Ptr : Named;
procedure Proc is
function Fff return access Some_Type is ... ;
begin
Ptr := Named (Fff); -- statically legal?
while still disallowing
function Bad return access Some_Type is
Local : aliased Some_Type;
begin
return Local'Access; -- illegal
It is also not clear to me that 3.10.2 (as modified by AIs 51 and 234) defines
the accessibility level of an anonymous access type of a function return object
- it defines the level of the object, but not of its type.
Note that in the case of a non-null access value, the accessibility level of the type
corresponds to the accessibility level of (that view of) the designated object. This
is typically what we are more interested in; the accessibility level of a function
result object of an elementary type is unimportant.
[Aside: It is curious, but harmless, that 3.10.2(10.2/3) applies even in the case
where the function result type is Integer. Noone cares about the accessibility level
of an unaliased elementary object, so it really doesn't matter what it is defined to be].
10.1/3 introduces a single bulleted-list item (which, in turn, encloses a nested bulleted
list).
Would it make sense to add another item immediately after that top-level item (i.e., a
top-level bulleted-list item inserted after 10.d.7/3) something along the lines of
In the case of a call to a function whose result type is an anonymous
access type, the accessibility level of the type of the result of
the function call is also determined by the point of call as described
above.
?
My understanding is that it was intended (although this intent may not have been captured
by the wording of the RM) that the following example should compile successfully and run
to completion without raising any exceptions.
procedure Test is
subtype Designated is Integer;
type Global_Ref is access all Designated;
Global_Ptr : Global_Ref;
procedure Nested is
type Local_Ref is access all Designated;
Local_Ptr : Local_Ref;
function Func (Is_Local : Boolean) return access Designated is
begin
return Result : access Designated do
if (Result in Global_Ref) = Is_Local then
raise Program_Error;
end if;
declare
Sao : access Designated := Result;
begin
if (Sao in Global_Ref) = Is_Local then
raise Program_Error;
end if;
end;
end return;
end Func;
begin
Local_Ptr := Func (Is_Local => True);
Global_Ptr := Func (Is_Local => False);
end Nested;
begin
Nested;
end Test;
Do others agree about this?
Thanks to Randy for discussions about these issues.
****************************************************************
From: Steve Baird
Sent: Monday, August 9, 2011 4:47 PM
> My understanding is that it was intended (although this intent may not
> have been captured by the wording of the RM) that the following
> example should compile successfully and run to completion without
> raising any exceptions.
>
> Local_Ptr := Func (Is_Local => True);
> Global_Ptr := Func (Is_Local => False);
>
With the changes I suggested, we'd need explicit conversions here
Local_Ptr := Local_Ref (Func (Is_Local => True));
Global_Ptr := Global_Ref (Func (Is_Local => False));
because of 8.6(27.1/3)'s requirement for an implicit conversion that
"... the name or expression shall denote a view with an accessibility
level for which the statically deeper relationship applies ...".
This correction does not affect the main point of the previous message.
****************************************************************
Questions? Ask the ACAA Technical Agent