!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; -- Should this be illegal? 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); -- 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; !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. ****************************************************************