Version 1.3 of ai05s/ai05-0284-1.txt
!standard 3.10.2(10/2) 12-03-09 AI05-0284-1/02
!class binding interpretation 11-11-13
!status Amendment 2012 12-03-09
!status ARG Approved 9-0-1 12-02-25
!status work item 11-11-13
!status received 11-08-07
!priority Low
!difficulty Medium
!qualifier Omission
!subject Accessibility of anonymous access returns
!summary
The accessibility level of the type of the result of a function call
to a function with an anonymous access result is determined by the point of call.
!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?? (No, it's already
covered.)
(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
For (2), add a paragraph indented the same as 3.10.2(10.1/3) [but not bulleted]
before 3.10.2(10.7/3): [This is part of the rule represented by 3.10.2(10.1/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
For (1), 3.10.2(19.3/3) defines the statically deeper relationship for an anonymous
access in a return statement. So we have the needed rule, nothing additional is
needed.
For (2), 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, the following is legal:
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;
!corrigendum 3.10.2(10/2)
Replace the paragraph:
- 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.
by:
@Comment{See the conflict file for the real wording}
!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