!standard 6.3.1(10.1/2) 14-05-14 AI05-0107-1/01 !class binding interpretation 14-05-14 !status work item 14-05-14 !status received 14-02-28 !priority Low !difficulty Easy !qualifier Omission !subject Is an access to a By_Protected_Procedure interface procedure a protected access? !summary An access to a By_Protected_Procedure interface prefixed view is has convention protected and can be used as a protected access. !question An proposed ACATS B-Test contains a case like the following: type Intf is synchronized interface; procedure PPN1 (Param : in out Intf) is abstract with Synchronization => By_Protected_Procedure; end Nested; procedure Sink2 (P : access protected procedure) is begin null; -- Eat an access-to-parameterless-protected-procedure. end Sink2; procedure Foo (Intf_In_Out_Parm : in out Nested.Intf'Class) is begin Sink2(Intf_In_Out_Parm.PPN1'access); -- (1) end Foo; The test expects (1) to be legal, but the convention of a prefixed view is intrinsic (by 6.3.1(10.1/2)), and that does not match the convention "protected" required by an access-to-protected-procedure. The only special thing one can do with a protected procedure is to take 'Access of it for an access-to-protected-procedure type. It seems odd that this case does not work. Should it? (Yes.) !recommendation (See Summary.) !wording Modify 6.3.1(10.1/2): * any prefixed view of a subprogram (see 4.1.3){, unless the subprogram has synchronization kind (see 9.5) By_Entry or By_Protected_Procedure. A prefixed view of a subprogram with a synchronization kind of By_Entry has calling convention *entry*; a prefixed view of a subprogram with a synchronization kind of By_Protected_Procedure has calling convention *protected*. AARM Reason: The part of the rule about synchronization kind By_Protected_Procedure allows such prefixed views to have 'Access taken of them for an access-to-protected-procedure type. The entry part is just for consistency (there is no access-to-entry type in Ada). !discussion The prefixes of interest are prefixed views where the subprogram has synchronization kind By_Protected_Procedure. (Aside: It's a bit odd that we don't have a matching By_Protected_Function synchronization kind, but that seems unnecessary for now.) The question was raised in mail whether a subprogram with By_Entry or By_Protected_Procedure should still have the Ada convention (thus, still being allowed as the prefix of Access for a *normal* access-to-procedure). This clearly would require a wrapper of some sort, but as it seems to be a normal subprogram for many other uses it's unclear that we need to prevent it. We could just declare such subprograms to have convention Intrinsic so this doesn't need to be done. [Slightly related worry: 4.1.3(8) and 4.1.3(9.1/2) seem to both match in the case of a reference to a protected subprogram of a protected type with an interface. Such a protected type is a tagged type, and a protected subprogram is considered a subprogram (by the definition in 9.5.1(1)). If the subprogram implements some operation of the interface, it seems that all of the conditions of 4.1.3(9.1/2 and 9.2/3) are met. Similarly, all of the conditions of 4.1.3(8) are met. Is this name a prefixed view or not? RLB.] !corrigendum 6.3.1(10.1/2) @drepl @xinbull @dby @xinbull; a prefixed view of a subprogram with a synchronization kind of By_Protected_Procedure has calling convention @i> !ASIS No ASIS effect. !ACATS test ACATS 4.0 B-Test B950001 contains two commented out examples of this (137 and 147); those should be replaced if this AI is adopted. An ACATS C-Test could be created to ensure this construct works. !appendix From: Randy Brukardt Sent: Friday, February 28, 2014 8:39 PM The Ada 2012 part of a fairly recent ACATS B-Test contains the following (simplified down to the bare facts): package Nested is type Intf is synchronized interface; procedure PPN1 (Param : in out Intf) is abstract with Synchronization => By_Protected_Procedure; end Nested; procedure Sink2 (P : access protected procedure) is begin null; -- Eat an access-to-parameterless-protected-procedure. end Sink2; procedure Foo (Intf_In_Out_Parm : in out Nested.Intf'Class) is begin Sink2(Intf_In_Out_Parm.PPN1'access); -- OK end Foo; The test expects this to be legal. Gnat doesn't like it, which caused me to look at it more carefully. The GNAT error message isn't enlightening -- it claims that PPN1 is not a prefix of Intf'Class, which is clearly wrong, and GNAT has no problem with similar expressions elsewhere in the test, so something else is going on. I started wondering if this actually makes sense. What are the requirements of the prefix of an access-to-protected-subprogram? The RM doesn't have anything special; the only different I can find is that the calling convention of an access-to-protected-procedure has convention "protected" rather than "Ada". So that begs the question of what is the calling convention of "Intf_In_Out_Parm.PPN1"? Certainly, in the absence of By_Protected_Procedure, it would be "Ada". 6.3.1(12) does not mention this case, also suggesting that it is "Ada". OTOH, the entire point of the declaration is to ensure that the completion (really "implemented by") is always a protected procedure. So it doesn't make much sense to have the convention be "Ada". Should the calling convention of such a subprogram be "protected"? Or is there some hardship that might happen if we insisted on that? And if the convention isn't "protected", precisely what value does this declaration have? We would hope to be able to use such a subprogram just like a protected procedure, analogous to the By_Entry case -- and the only unique thing we can do with a protected procedure is use it as the prefix of 'Access to get an access-to-protected-procedure. In any case, I'll comment out these cases for now. The RM certainly doesn't clearly provide the answer I assumed when I wrote that part of the test, so making a requirement like this isn't justified (and it's not critical to the value of the test). **************************************************************** From: Tucker Taft Sent: Friday, February 28, 2014 9:05 PM > ... > So that begs the question of what is the calling convention of > "Intf_In_Out_Parm.PPN1"? Certainly, in the absence of > By_Protected_Procedure, it would be "Ada". 6.3.1(12) does not mention > this case, also suggesting that it is "Ada". OTOH, the entire point of > the declaration is to ensure that the completion (really "implemented > by") is always a protected procedure. So it doesn't make much sense to > have the convention be "Ada". ... Agreed. It would make sense, I guess, to make a prefixed view of such a procedure have convention access-to-protected-procedure. If you asked for the convention of PPN1 itself (or a non-abstract equivalent thereof), as opposed to Intf_In_Out_Parm.PPN1, then I think you should get "Intrinsic." The RM says that the prefixed view of a subprogram is Intrinsic, but this is probably one of those places where a "protected subprogram" is not just a special case of a subprogram. ****************************************************************