!standard 12.5.4(5) 12-02-13 AI05-0288-1/01 !class binding interpretation 12-02-13 !status Amendment 2012 12-02-13 !status work item 12-02-13 !status received 11-12-19 !priority Low !difficulty Easy !qualifier Omission !subject Conformance of formal access-to-subprogram types !summary Subtype conformance is required for actual types for generic formal access-to-subprogram types. !question 12.5.4(5) only requires mode conformance for actual types for generic formal access-to-subprogram types. However, here's a case where this appears to cause a problem: package Pack0 is procedure Proc (N : Natural); end Pack0; with Text_IO; package body Pack0 is procedure Proc (N : Natural) is begin Text_IO.Put_Line (Natural (N)); end Proc; end Pack0; generic type ACC is access procedure (N : Natural); package Pack1 is procedure Test1 (A : out ACC); end Pack1; with Pack0; package body Pack1 is procedure Test1 (A : out ACC) is begin A := Pack0.Proc'access; end Test1; end Pack1; package Pack2 is procedure Cause_A_Problem; end Pack2; with Pack1; package body Pack2 is type Actual_Acc is access procedure (N : Integer); package New_Pack1 is new Pack1 (Actual_Acc); procedure Cause_A_Problem is X : Actual_Acc; begin New_Pack1.Test1 (X); X (-1); -- PROBLEM end Cause_A_Problem; end Pack2; If Pack0.Proc'access were used with an expected type Actual_Acc, it would be illegal by 3.10.2(32). But since only mode conformance, not subtype conformance, is required when matching generic formal access-to-subprogram types, this appears to be a way to get around this restriction and pass a value that doesn't belong to the actual subprogram parameter's subtype. As a result, there is no any language rule that would make the program illegal, nor is there any point at which a Constraint_Error should be raised on the parameter -1. Is a fix is needed? (Yes.) !recommendation (See summary.) !wording Change "mode conformance" to "subtype conformance" in 12.5.4(5), and delete all of the convention text (this is implied by subtype conformance). Delete 12.5.4(5.a). !discussion This change is potentially incompatible, although access-to-subprogram formals are rarely used, so this should not happen often. An alternative to requiring subtype conformance for actual types would be to require rechecking in the specification and assume-the-worst in the generic body. The rechecking in the specification already follows from the language rules; the questioner's example clearly avoids doing anything in the specification. Similarly, 'Access of subprograms declared in the generic is already illegal in the generic body. So this cannot be a problem. This leaves two holes that would have to be plugged: 'access of (more) global subprograms and conversions from more global access-to-subprogram types to the formal type. This clearly would be less incompatible (only making unlikely cases illegal), but the rules needed are more complex (and needed in two places), so we adopt the simpler rule. !corrigendum 12.5.4(5) @drepl For a formal access-to-subprogram subtype, the designated profiles of the formal and the actual shall be mode conformant, and the calling convention of the actual shall be @i if and only if that of the formal is @i. @dby For a formal access-to-subprogram subtype, the designated profiles of the formal and the actual shall be subtype conformant. !ACATS Test An ACATS B-Test should be created to check that the rules are enforced. !ASIS No ASIS impact. !appendix !topic Problem with generic formal access-to-subprogram types !reference 12.5.4(5) !from Adam Beneschan 11-12-19 !discussion 12.5.4(5) [and the succeeding AARM paragraph say]: For a formal access-to-subprogram subtype, the designated profiles of the formal and the actual shall be mode conformant mode-conformant, and the calling convention of the actual shall be protected if and only if that of the formal is protected. 5.a Reason: We considered requiring subtype conformance here, but mode conformance is more flexible, given that there is no way in general to specify the convention of the formal. However, here's a case where this appears to cause a problem: package Pack0 is procedure Proc (N : Natural); end Pack0; with Text_IO; package body Pack0 is procedure Proc (N : Natural) is begin Text_IO.Put_Line (Natural (N)); end Proc; end Pack0; generic type ACC is access procedure (N : Natural); package Pack1 is procedure Test1 (A : out ACC); end Pack1; with Pack0; package body Pack1 is procedure Test1 (A : out ACC) is begin A := Pack0.Proc'access; end Test1; end Pack1; package Pack2 is procedure Cause_A_Problem; end Pack2; with Pack1; package body Pack2 is type Actual_Acc is access procedure (N : Integer); package New_Pack1 is new Pack1 (Actual_Acc); procedure Cause_A_Problem is X : Actual_Acc; begin New_Pack1.Test1 (X); X (-1); -- PROBLEM end Cause_A_Problem; end Pack2; If Pack0.Proc'access were used with an expected type Actual_Acc, it would be illegal by 3.10.2(32). But since only mode conformance, not subtype conformance, is required when matching generic formal access-to-subprogram types, this appears to be a way to get around this restriction and pass a value that doesn't belong to the actual subprogram parameter's subtype. As a result, I don't see any language rule that would make the program illegal, nor do I see any point at which a Constraint_Error should be raised on the parameter -1. **************************************************************** From: Steve Baird Sent: Wednesday, January 4, 2012 5:50 PM > 12.5.4(5) [and the succeeding AARM paragraph say]: > > For a formal access-to-subprogram subtype, the designated profiles of > the formal and the actual shall be mode conformant mode-conformant, > and the calling convention of the actual shall be protected if and > only if that of the formal is protected. > > 5.a Reason: We considered requiring subtype conformance here, but mode > conformance is more flexible, given that there is no way in general to > specify the convention of the formal. > > However, here's a case where this appears to cause a problem: > ... I think Adam has identified a real problem here. It seems clear that we don't want to allow a value of an access-to-subprogram type to denote a subprogram whose profile is not subtype-conformant with the access type's designated profile. I see two approaches - tighten up the actual/formal contract to require subtype conformance, or keep it loose and deal with it. Either 1) Change the rule that Ada cited to require subtype conformance. If we take this approach, we probably also need to beef up the required support for specifying the Convention aspect of a formal access-to-subp type in order to address the concern described in the AARM note. or 2) In 6.3.1, we already have The profile of a generic formal subprogram is not subtype-conformant with any other profile. We could add something similar to say that the designated profile of a generic formal access-to-subprogram type is not subtype conformant with any other profile. This have the effect of disallowing the problematic 'Access in Adam's example. Either change is incompatible. It's not clear (at least to me) whether the incompatibilities associated with one or the other approach would be more likely to be a problem in practice. I lean towards approach #1 (tighten up the conformance rules). Why take away useful functionality from someone who is "doing things right" (i.e., already meeting the subtype-conformance requirement)? I could be argued out of this position if someone could convince me that the incompatibilities associated with this approach are substantially worse than those of the other. What do others think? P.S. The above message has not been approved by the hyphen police. **************************************************************** From: Gary Dismukes Sent: Wednesday, January 4, 2012 6:18 PM ... > It seems clear that we don't want to allow a value of an > access-to-subprogram type to denote a subprogram whose profile is not > subtype-conformant with the access type's designated profile. Yes, clearly. > What do others think? I agree that option 1 looks like the way to go. > P.S. The above message has not been approved by the hyphen police. FWIW, I'll grant my approval (except that I'd use two hyphens for the dash in the sentence that begins "I see two approaches - tighten up ...";-). **************************************************************** From: Tucker Taft Sent: Wednesday, January 4, 2012 6:45 PM Choosing (1) below makes sense, since for formal subprograms with parameters of an access-to-subprogram type, we require subtype conformance of the designated profiles for the corresponding acc-to-subp parameters. This is because *mode* conformance of two subprograms requires *subtype* conformance between the designated profiles of acc-to-subp parameters. In fact there is no circumstance other than this special case where we permit only mode conformance of designated profiles. I'm not sure why you think we need to beef up the convention specification. We haven't worried about that before, even though we require subtype conformance of designated profiles for matching of acc-to-subp parameters of formal subprograms. A completely different approach is to leave it at mode conformance, and then recheck uses of 'Access or conversion in the spec, and disallow use of 'Access or conversion in the body with these types. Perhaps that was our original intent? **************************************************************** From: Steve Baird Sent: Wednesday, January 4, 2012 6:58 PM > I'm not sure why you think we need to beef up the convention > specification. We haven't worried about that before, even though we > require subtype conformance of designated profiles for matching of > acc-to-subp parameters of formal subprograms. Maybe you are right. I was just trying to address the concern mentioned in the AARM, but perhaps it is a small enough problem that it can be ignored. I don't feel strongly about it. > A completely different approach is to leave it at mode conformance, > and then recheck uses of 'Access or conversion in the spec, and > disallow use of 'Access or conversion in the body with these types. > Perhaps that was our original intent? I don't think that was the original intent, but I think it would work. I think I'd still prefer simply requiring subtype conformance (proposal #1). If we took the approach that you've outlined, then there would be an obvious question about why we don't do something similar for 'Access of a formal subprogram. So we'd have our choice of either introducing an obvious inconsistency or (if we decided to deal with formal subprograms too) expanding the scope of the change well beyond what is needed to fix the original problem. Still, I think the approach you describe is an interesting idea that would work, modulo the drawback of disallowing uses of 'Access in a generic body in cases where proposal #1 would allow them. **************************************************************** From: Randy Brukardt Sent: Wednesday, January 4, 2012 11:15 PM > Choosing (1) below makes sense, since for formal subprograms with > parameters of an access-to-subprogram type, we require subtype > conformance of the designated profiles for the corresponding > acc-to-subp parameters. This is because *mode* conformance of two > subprograms requires *subtype* conformance between the designated > profiles of acc-to-subp parameters. > In fact there is no circumstance other than this special case where we > permit only mode conformance of designated profiles. That does make the sense. But see below. > I'm not sure why you think we need to beef up the convention > specification. We haven't worried about that before, even though we > require subtype conformance of designated profiles for matching of > acc-to-subp parameters of formal subprograms. As Steve noted, the existing AARM note (12.5.4(5.a)) gives that as the only sane reason for requiring mode conformance. "More flexible" doesn't make much sense when we're requiring subtype conformance everywhere else. And I have to say this is one of the lamest Ada 9x AARM notes; sure "mode conformance" is more flexible. But so is "type conformance", or not requiring any conformance at all! One would have hoped something had been said about the semantic ramifications. > A completely different approach is to leave it at mode conformance, > and then recheck uses of 'Access or conversion in the spec, and > disallow use of 'Access or conversion in the body with these types. > Perhaps that was our original intent? I suspect that is what currently happens. The (legality) rules of 'Access and conversion surely get rechecked in specs, and they require subtype conformance. 'Access in the body is almost always illegal anyway. The prefix can't be anything declared inside the generic (that would violate 3.10.2(32/3) for a formal access type). So the "hole" only involves 'Access in the body involving (more) global subprograms (something that should hardly exist in practice, although it's the example Adam showed), and conversions between access types (which seem unlikely, why would someone have two types with the same profile sitting around? Especially when one is a formal. Accessibility checks would make it obnoxious to try to declare such a thing locally.). That suggests that the least incompatible solution would be to just disallow those ('Access and conversions to a formal access-to-subprogram type) in generic bodies -- but we probably will need to do some sort of testing to verify (or disprove) that. [That surely would "fix" Adam's original example, and any corollaries.] It seems to me to be more likely that the formal access-to-subprogram mismatches would happen and be newly rejected. But I don't care strongly about this (and it is probably easier to implement pure subtype conformance in a sharing environment; mode conformance for regular formal subprograms requires thunks). **************************************************************** From: Brad Moore Sent: Saturday, January 21, 2012 1:25 PM > That suggests that the least incompatible solution would be to just > disallow those ('Access and conversions to a formal > access-to-subprogram type) in generic bodies Just to clarify, we would still be allowing Unchecked_Conversions to a formal access-to-subprogram type in generic bodies? **************************************************************** From: Randy Brukardt Sent: Saturday, January 21, 2012 2:58 PM Sure, we don't have rules to prevent those in any funny case. But they're not guaranteed to work (irrespective of this case), so I don't think that matters. ****************************************************************