Version 1.3 of ai05s/ai05-0284-1.txt

Unformatted version of ai05s/ai05-0284-1.txt version 1.3
Other versions for file 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; -- Should this be illegal? (Yes, it is.) 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); -- Legal. 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:
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