!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) @drepl @xbullet 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 @fa or the result of a function call is that of the innermost master that evaluates the @fa or function call.> @dby @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. ****************************************************************