!standard 03.10.02 (02) 00-06-16 AI95-00235/03 !class binding interpretation 00-05-31 !status received 00-05-09 !status work item 00-05-09 !priority High !difficulty Medium !subject Resolving 'Access. !summary The prefix type of 'Access (and 'Unchecked_Access) can be used to resolve the expected access type. !question 3.10.2(2) requires that the expected type of 'Access (and 'Unchecked_Access) is "a single access type". This means that some expressions which might be resolved are illegal: type Int_Ptr is access all Integer; type Float_Ptr is access all Float; function Zap (Val : Int_Ptr) return Float; function Zap (Val : Float_Ptr) return Float; ... Value : aliased Integer := 10; Result1 : Float := Zap (Value'access); -- Legal? (Yes.) Result2 : Float := Zap (Int_Ptr'(Value'access)); -- OK. Existing Ada 95 compilers vary widely as to whether or not they allow expressions like Result1's initializer. Should we allow additional flexibility here? (Yes.) !recommendation (See summary.) !wording Replace 3.10.2(2) with: For an attribute_reference with attribute_designator Access (or Unchecked_Access -- see 13.10), the expected type shall be a single access type whose designated type covers the type of the prefix, or, if the type of the prefix is D'Class, whose designated type is D, or whose designated profile is type conformant with that of of the prefix. [The prefix of such an attribute_reference is never interpreted as an implicit_dereference or parameterless function_call (see 4.1.4).] The designated type or profile of the expected type of the attribute_reference is the expected type or profile for the prefix. !discussion A compiler survey of the most popular compilers shows that two compilers implement the existing RM wording reasonably closely, while four other compilers allow varying degrees of overloading resolution in this case. The easiest course of action would be simply to confirm the RM, and require the implementors to conform. However, it is clear that real Ada users trip over this rule periodically. It was a large Ada user that contacted the ACAA with the fact that compilers differ in their implementation of this rule, which eventually led to the creation of this AI. The user problem is most severe when an anonymous access type is involved: function Do_It (Obj : access Integer) return Boolean; function Do_It (Obj : access Float) return Boolean; if Do_It (Value'Access) then ... -- Illegal by original RM rule. (Code like this is common in interfacing packages, where an anonymous access type used to implement *p parameters in functions [because In Out parameters are not allowed there]). To work around the problem caused by the original RM rule, a named access type has to be introduced, so that it can be used in a qualified expression: if Do_It (Int_Ptr'(Value'Access)) then ... -- OK. But this is not quite equivalent, because the accessibility rules for anonymous access types is different from named access types. (The use of the qualified expression changes the accessibility check for the Access attribute from the anonymous type to the named type.) Thus, the user will have to declare an access type in the scope of each call, or will have to change to using 'Unchecked_Access. Since some compilers allow the resolution of expressions like that in the question and in the example above, it is likely that real-world systems depend on being able to resolve these expressions. If the rule 3.10.2(2) was confirmed and compilers changed to conform, this existing user code would break for no good reason. Therefore, we adopt a liberalized rule. The new rule has to be careful to include the "single access type" wording, in order that 'Access not be allowed in type conversions or other contexts where a specific type is not identified. !corrigendum 3.10.02(2) @drepl For an @fa with @fa Access (or Unchecked_Access -- see 13.10), the expected type shall be a single access type; the @fa of such an @fa is never interpreted as an @fa. If the expected type is an access-to-subprogram type, then the expected profile of the @fa is the designated profile of the access type. @dby For an @fa with @fa Access (or Unchecked_Access -- see 13.10), the expected type shall be a single access type whose designated type covers the type of the @fa, or, if the type of the @fa is D'Class, whose designated type is D, or whose designated profile is type conformant with that of the @fa. The @fa of such an @fa is never interpreted as an @fa or parameterless @fa (see 4.1.4). The designated type or profile of the expected type of the @fa is the expected type or profile for the @fa. !ACATS test ACATS test B3A2016.A, introduced in December 1999, tests this issue. A C-test should be created out of the example test circulated in June 2000. !appendix From: Randy Brukardt Sent: Tuesday, May 9, 2000 5:20 PM At the recent ARA meeting, Robert Dewar expressed some concern about a new ACATS test which is intended to check 3.10.2(2) for objects. (There was no test for this rule in the past.) This rule says that the prefix of an access attribute is not used to resolve the expression which contains it. I created the new ACATS test from a test case that was submitted by a large Ada user. They had run into problems with different compilers supporting different resolution algorithms. My experiments with the test program shows that compilers implement the rule differently, ranging from (almost) strict RM to using the maximum information. Robert was concerned that forcing compilers to follow the RM rules could break existing user code that depends on this "feature"; he thought it was especially likely to occur in interfacing code. (Hopefully, Robert will expand on this concern.) The basic test case is the following: type Int_Ptr is access all Integer; type Char_Ptr is access all Character; type Float_Ptr is access all Float; function Zap (Val : Int_Ptr) return Float; function Zap (Val : Float_Ptr) return Float; ... Value : aliased Integer := 10; Result1 : Float := Zap (Value'access); -- ERROR: Ambiguous. Result2 : Float := Zap (Int_Ptr(Value'access)); -- ERROR: Type conversion (8.6(27)). Result3 : Float := Zap (Int_Ptr'(Value'access)); -- OK. While the only legitimate interpretation of Value'access is as an Int_Ptr, 3.10.2(2) makes it clear that any access type matches it; thus we cannot resolve between the two cases of Zap. A few Ada compilers do get this right. --- More recently, I noticed that the rule says "single access type", not "single GENERAL access type", so I added the following test case (not yet issued): type Int_Ptr is access all Integer; type Pool_Int_Ptr is access Integer; function Zip (Val : Int_Ptr) return Float; function Zip (Val : Pool_Int_Ptr) return Float; ... Value : aliased Integer := 10; Result4 : Float := Zip (Value'access); -- ERROR: Ambiguous. Result5 : Float := Zip (Int_Ptr(Value'access)); -- ERROR: Type conversion (8.6(27)). Result6 : Float := Zip (Int_Ptr'(Value'access)); -- OK. Again, the only legitimate interpretation of Value'access is as an Int_Ptr ('access never returns a pool-specific access type), but again we can't use this. 3.10.2(2) makes it clear that any access type matches it for resolution purposes; thus we cannot resolve between the two cases of Zip. No Ada compiler I tried gets this example right. --- We have three choices (with the third choice open-ended): 1) We can simply file this as No Action, and direct the ACAA not to test it. I don't think this serves anyone well: compilers will continue to differ, vendors will get bug reports about their compilers being incompatible with the standard, and users will encounter problems porting code. It is clear this issue is of more than academic interest, as at least one real Ada user has encountered it in practice. Moreover, ACT is concerned about the effects of correcting their compiler; this implies to me that they also feel that it is a real issue. Therefore, I reject this choice. 2) We can confirm the standard. The ACAA will keep the test in the ACATS suite, and it will become effective July 1st. This means that several compilers will need to be changed, and some users may be impacted. This is the default action: if we do nothing at all, this is what will happen. 3) We can change the standard. I am somewhat uncomfortable about this option, as there is no technical problem with the language. We have done that at least once in the past, but in that case there was an existing ACATS test to which all compilers conformed: thus the language change had no impact on compilers or users. Indeed it brought the language into compliance with practice. In this case, we have compilers which DO follow the RM. A language change would impact those vendors (although not their users, as more expressions would be made legal). I'm not sure what the rule ought to be changed to if it is changed. I don't think that simply eliminating the rule works very well. Quite ugly expressions can be constructed that may be hard to resolve, especially if compilers take any advantage of the "single access type" rule. There also may be technical problems allowing 'access as the operand of a type conversion (what is the type if there is more than one possible general access type that matches the prefix? Do we need to "search" for all possible access types before deciding this??). One ugly case, with the declarations of the first example above: function Zop return Int_Ptr; function Zop return Char_Ptr; ... Value : aliased Integer := 10; Resultx : Float := Zap (Zop.all'access); This expression can be resolved, as there is only one interpretation where all of the types match, but do we really want to go through the work to allow it?? OTOH, changing 3.10.2(2) to say "single general access type" would make the rule match compilers more closely, and I think it is harmless. Whatever is done with the rule, I believe that the ACATS ought to test it, to insure that compilers all conform to the standard. Randy Brukardt ACAA Technical Agent. **************************************************************** From: Robert Dewar Sent: Tuesday, May 09, 2000 6:07 PM 1) It is better to use an example with access parameters, because in this case there *is* no easy fix, because there is no type name to use in a qualification, so a junk type access type has to be introduced which is quite unpleasant. 2) It is not right to say that we have compilers which "DO follow the RM", as you made it clear that "no Ada compiler I tried gets this right" for one of the examples. This means that if you choose option 2, then *all* compilers will need to be changed. 3) The only reason for not using the context to help resolve here seems to be the arbitrary Ada 83 rule that attributes must be resolved without using context (more precisely that the prefix of the attribute must be resolved without using context). But the 'Access operator was not in Ada 83, so it is not clear that makes sense. 4) We already made an exception to this Ada 83 principle for the case of access to subprogram, so why not access to object as well. 5) The idiom of using x'access and access parameters in calls, especially to interfaced routines in a foreign language is a common one. It is the cleanest workaround to the rule that you cannot have in out parameters in functions, as required for interfacing to many C functions for example. 6) Do we really do users a favor by fixing this? Yes, it is a problem for portability, but why value portability over consistency to such an extent that you will force lots of users to change their programs now instead of later. Portability is after all a user concern, so if we are going to argue portability, we also have to be concerned with the impact on users. In this case the impact would be significant. 7) If we have a choice between changing the test suite so that users can do MORE than they could before, and changing it so that they can do LESS than they could before, how is this a benefit. It seems clear that it is far more useful to users to take Randy's option three. 8) I object to the statement that the default is that the test goes in. No test should go into the suite without specific ARG discussion that includes issues of impact on users, and also value of the test. Please let's not get into a situation where changes to the tests once again tend to give the suite a bad name. The suite is there to help users, not to hurt them. 9) I sort of understand the idea that if several compilers get something "right" and several get it "wrong" that there is a tendency to think it is fairer to change the ones that are "wrong". However, in this case (a) there is no compiler that really gets it right and (b) this in any case is a principle designed with compiler writers benefits in mind rather than user benefits. Note that we have quite a few times changed the clear language in the RM in a way that makes correct compilers change under the influence of incorrect compilers doing things wrong, if on reflection we feel that wrong is right. An excellent example of this is the non- static status of System.Bit_Order. GNAT carefully made this non-static and got lots of user complaints. Green Hills (and I assume other compilers using the same front end made it static which was clearly wrong. GNAT made the change because it was clearly in the best interests of users. 10) I think that changing this is in accordance with the principle of least surprise. The overloading rule after all should be that if there is only one interpretation and it is not likely to cause confusion, then that's the one that should be used. We compromise this for the benefit of implementation simplicity sometimes, but I don't see that this principle applies in this case. 11) The original Ada 83 rule that prefixes have to be resolved without context is not particularly worrisome, as there are very few cases where it would be annoying. But 'Access is really a completely different kind of beast. It might well be an operator in the language, in which case of course this would work, but for various reasons it ended up as an attribute but I see no reason why this choice should cause ambiguity problems. 12) I suspect that the change required in compilers is small either way. Certainly in GNAT it is trivial to make the change (we almost did it, and then I complained that it would be a real pain to users, so we hesitated for now). It was an easy-to-find two line change. Let's not use the argument of compilers being difficult to change, until we find that this is really true. Remember that *all* compilers will have to change if we choose Randy's option number 2. 13) I really dislike rules where the resolution depends on whether a type is a general or pool-specific access type, that seems really junky and quite unintuitive. For all these reasons, my order of preference is 3/1/2 in Randy's choices. I realize that a little work is needed for choice 3, and so let's for now look at choice 3, and formulate the EXACT replacement rule, before we decide whether to adopt it or not. **************************************************************** From: Pascal Leroy Sent: Wednesday, May 10, 2000 4:09 AM > Robert was concerned that forcing compilers to follow the RM rules could > break existing user code that depends on this "feature"; he thought it was > especially likely to occur in interfacing code. (Hopefully, Robert will > expand on this concern.) This is a rather weak argument. Compiler writers have been fixing bugs for about 15 years, and we all know that occasionally fixing a bug will cause grief and sorrow because some users will discover that their code depended on the bug. Such situations are normally dealt with by a frank and open discussion between the user and the vendor. The outcome may be anything from "you've got to change your code" to "we are going to provide a bug-compatibility option just for you". Bug-compatibility is certainly not a good reason for changing the language. The only valid question is: would the language be more useful with the proposed change? I am tempted to say yes, but to make a definite answer I would need to see a precise proposal, not just some hand-waving. > 3) We can change the standard. I am somewhat uncomfortable about this > option, as there is no technical problem with the language. We have done > that at least once in the past, but in that case there was an existing ACATS > test to which all compilers conformed: thus the language change had no > impact on compilers or users. Indeed it brought the language into compliance > with practice. In this case, we have compilers which DO follow the RM. A > language change would impact those vendors (although not their users, as > more expressions would be made legal). Note that in the case(s) where we changed the language, the change was rather obvious; although I'm sure it took time and effort to come up with the correct wording, the intent at least was pretty clear. In this case on the other hand, it is very much unclear what the language should say (ie, how much information do we want to use to lift ambiguities?). > OTOH, changing 3.10.2(2) to say "single general access type" would make the > rule match compilers more closely, and I think it is harmless. No, it doesn't work. 3.10.2(2) applies to any occurrence of 'Access, including those cases where the prefix is a subprogram. The phrases "single access type" covers access-to-subprogram as well as access-to-object types. You could come up with a similar ambiguity if one access type was an access-to-object and the other an access-to-subprogram (and incidentally our compiler catches the ambiguity in this case). **************************************************************** From: Randy Brukardt Sent: Wednesday, May 10, 2000 12:09 PM Pascal said: > Note that in the case(s) where we changed the language, the change was rather > obvious; although I'm sure it took time and effort to come up with the correct > wording, the intent at least was pretty clear. In this case on the other hand, > it is very much unclear what the language should say (ie, how much information > do we want to use to lift ambiguities?). I agree; I tried to say this in my original post, but Pascal says it better. Anyway, I think that someone who wants to change the language (Robert?) should take the lead in providing a proposal for revising 3.10.2(2). I haven't been able to come up with anything simple that provides the right answer and doesn't run into problems. So while I'm sympathetic to the idea, I don't see how to realize it. > No, it doesn't work. 3.10.2(2) applies to any occurrence of > 'Access, including those cases where the prefix is a > subprogram. The phrases "single access type" covers > access-to-subprogram as well as access-to-object types. You > could come up with a similar ambiguity if one access type was > an access-to-object and the other an access-to-subprogram > (and incidentally our compiler catches the ambiguity in this case). You are right of course. The existing ACATS test includes this case; I didn't include it in my original message because it isn't particularly interesting. **************************************************************** From: Tucker Taft Sent: Wednesday, May 10, 2000 11:33 AM Robert Dewar wrote: > ... > 3) The only reason for not using the context to help resolve here > seems to be the arbitrary Ada 83 rule that attributes must be resolved > without using context (more precisely that the prefix of the attribute > must be resolved without using context). But the 'Access operator was > not in Ada 83, so it is not clear that makes sense. This is not quite right. We are *not* talking about problems resolving the prefix, which in Ada 83 and Ada 95, must generally be unambiguous using no context (the only exception being 'access for access-to-subp). We are talking about resolving the surrounding function call. > 4) We already made an exception to this Ada 83 principle for > the case of access to subprogram, so why not access to object as well. Again, the exception for access-to-subp refers to resolving the prefix. In this case, the problem is resolving the enclosing function call. If you look at the wording, there is a chicken-and-egg problem if we allow the type of the prefix to help resolve the enclosing function call, because we are currently using the enclosing function call to resolve the prefix in the case of access-to-subp. The rule for resolving the access-to-subp prefix presumes there is only one access type coming "down" from outside. Of course, there are already chicken-and-egg cases during overloading, but the wording for 'access will require significant work to make sure that the access-to-subp case still works OK. > > 5) The idiom of using x'access and access parameters in calls, especially > to interfaced routines in a foreign language is a common one. It is the > cleanest workaround to the rule that you cannot have in out parameters in > functions, as required for interfacing to many C functions for example. Since C doesn't support overloading, I wonder whether interfacing to C is a great example in general. > > 6) Do we really do users a favor by fixing this? Yes, it is a problem > for portability, but why value portability over consistency to such an extent > that you will force lots of users to change their programs now instead of > later. Portability is after all a user concern, so if we are going to argue > portability, we also have to be concerned with the impact on users. In this > case the impact would be significant. This really means that you can't in fact overload functions where the only difference is which designated types their access parameters have. > ... > 11) The original Ada 83 rule that prefixes have to be resolved without > context is not particularly worrisome, as there are very few cases where > it would be annoying. But 'Access is really a completely different kind > of beast. It might well be an operator in the language, in which case of > course this would work, but for various reasons it ended up as an attribute > but I see no reason why this choice should cause ambiguity problems. As mentioned above, this has little to do with the resolution of the prefix. > ... > 13) I really dislike rules where the resolution depends on whether a type > is a general or pool-specific access type, that seems really junky and > quite unintuitive. > > For all these reasons, my order of preference is 3/1/2 in Randy's choices. > I realize that a little work is needed for choice 3, and so let's for now > look at choice 3, and formulate the EXACT replacement rule, before we decide > whether to adopt it or not. I am sympathetic with this, but as indicated above, it is not just following in the footsteps of the access-to-subp wording, because that is focused on an overload prefix, where here we are focused on an overloaded enclosing function call. In fact, the access-to-subp wording actually causes more trouble for dealing with an overloaded enclosing call. Perhaps something like this would work for 3.10.2(2): Name resolution rules: For an attribute_reference with attribute_designator Access (or Unchecked_Access -- see 13.10), the expected type shall be a single access type whose designated type covers the type of the prefix, or whose designated profile is type conformant with that of the prefix. This is fairly close to the wording for allocators [4.8(3)]. It is a bit of an unorthodox use of the "shall be a single blah type" but I think it is pretty clear how to implement this: Once you apply the filtering based on designated type/profile matching, there can't be any more ambiguity to be resolved by context. **************************************************************** From: Robert A Duff Sent: Wednesday, May 10, 2000 3:39 PM > 11) The original Ada 83 rule that prefixes have to be resolved without > context is not particularly worrisome, as there are very few cases where > it would be annoying. But 'Access is really a completely different kind > of beast. It might well be an operator in the language, in which case of > course this would work, but for various reasons it ended up as an attribute > but I see no reason why this choice should cause ambiguity problems. It's not really true that 'Access could just as well be an operator, because there are no operators that take subprograms as parameters. Subprograms are not values, and do not have types -- they have profiles instead. **************************************************************** From: Robert A Duff Sent: Wednesday, May 10, 2000 3:37 PM To: ada-comment@ada-auth.org > Perhaps something like this would work for 3.10.2(2): > > Name resolution rules: > > For an attribute_reference with attribute_designator Access (or > Unchecked_Access -- see 13.10), the expected type shall be > a single access type whose designated type covers the type of > the prefix, or whose designated profile is type conformant > with that of the prefix. Thank you, Tucker. I tried to come up with wording today, and failed. The above sounds exactly right, if we want to make this language change. I suppose I could go along with this language change; I'm open to either choice at this point. I do think this issue is one where we need to have the exact RM wording to argue intelligently about it. I think the difference between pool-specific and general access types should *not* be used to resolve these things, and the above wording achieves that. Randy, is it really true that some compilers use the pool-specific/general distinction to resolve these cases? Which ones? **************************************************************** From: Randy Brukardt Sent: Wednesday, May 10, 2000 4:10 PM > > Perhaps something like this would work for 3.10.2(2): > > > > Name resolution rules: > > > > For an attribute_reference with attribute_designator Access (or > > Unchecked_Access -- see 13.10), the expected type shall be > > a single access type whose designated type covers the type of > > the prefix, or whose designated profile is type conformant > > with that of the prefix. > > Thank you, Tucker. I tried to come up with wording today, and failed. > The above sounds exactly right, if we want to make this language > change. I suppose I could go along with this language change; I'm open > to either choice at this point. On first glance, this looks pretty good. It clearly solves most of the problems by leaving the "single access type" wording, which we need to avoid using 'Access in type conversions. One question, though, how does this work if the prefix is overloaded? That is, given the third example in my original message, is it legal or illegal (and why?) > I do think this issue is one where we need to have the exact RM wording > to argue intelligently about it. Now that is a first for Bob: admitting that extra RM wording is necessary. :-) :-) > I think the difference between pool-specific and general access types > should *not* be used to resolve these things, and the above wording > achieves that. Randy, is it really true that some compilers use the > pool-specific/general distinction to resolve these cases? Which ones? Yes, of course. (You don't think I make these things up, I hope?) All but one of the compilers I tried failed to detect the error in the second example in my original posting. And I thought you told me that your compiler failed that test as well. Specifically: Example 1 Example 2 GNAT 3.13a: No error No error Apex 3.0.2b: Error No error Janus/Ada 3.1.2: No error Error Of these three, only Janus/Ada matches Tucker's proposed wording. (And given it's market share, we probably can ignore it.) The reason some ACATS test is desperately needed here is exactly that the compilers all differ in what they allow and reject. If we change the language, then I would change the test(s) accordingly (and issuing them after the AI is approved by WG9) -- but I think it is a crime to let compilers vary all over the map here. **************************************************************** From: Gary Dismukes Sent: Wednesday, May 10, 2000 5:40 PM > One question, though, how does this work if the prefix is overloaded? That > is, given the third example in my original message, is it legal or illegal > (and why?) It looks to me like the proposed rule doesn't work for your third example (Zop.all'access). The phrase "covers the type of the prefix" implies that there is a single type for the prefix, but that doesn't address the overloaded case. I agree with you that it's not worth trying to make that case legal, but the rule needs to be fixed to address it. Maybe an extra rule is needed to say that the prefix shall only have a single interpretation, though that seems a bit ugly. **************************************************************** From: Robert Dewar Sent: Wednesday, May 10, 2000 7:55 PM Thanks Tuck for your careful analysis. Now you see why I am *not* the right person to propose the detailed (and no doubt delicate) fix. Your wording proposal change seems right to me (but I am probably not the right one to carefully vet such a proposal either :-) **************************************************************** From: Robert Dewar Sent: Thursday, May 11, 2000 4:37 AM Note that I definitely agree we should NOT change the reference manual here if we cannot come up with a simple change. But I think it is worth trying a little harder to do so, since this is really otherwise quite a surprising result, and I partiuclarly dislike resolution depending on whether something is a general access type or not. It is really nasty that adding ALL as a keyword should introduce ambiguities. (at least that's my understanding of the *current* rules). **************************************************************** From: Pascal Leroy Sent: Thursday, May 11, 2000 5:05 AM No, I think that the current rule is that ALL has no effect on name resolution. Our compiler (and maybe yours, if I am reading Randy's messages correctly) currently uses ALL when doing name resolution, but that's clearly a bug that will have to be fixed. **************************************************************** From: Robert Dewar Sent: Thursday, May 11, 2000 5:20 AM OK, if I misunderstand this, then fine, I am less concerned! **************************************************************** From: Robert A Duff Sent: Thursday, May 11, 2000 9:18 AM Randy, > One question, though, how does this work if the prefix is overloaded? That > is, given the third example in my original message, is it legal or illegal > (and why?) I've deleted that message. > Yes, of course. (You don't think I make these things up, I hope?) I wasn't trying to accuse you of making things up. ;-) I thought I must have misunderstood, or misremembered, what you said, because it seems like a compiler would have to go out of its way to get this wrong. >... All but > one of the compilers I tried failed to detect the error in the second > example in my original posting. And I thought you told me that your compiler > failed that test as well. It failed the B test as a whole, but it gets that part right. This is the part about Zup, right? We get: 227 Result20 : Float := Zup (Temperature'access); -- ERROR: Ambiguous * *****Error: LRM:8.6(31) Expression is ambiguous when interpreted as an ***** expression of the expected type Float, Returning first ***** interpretation * *****Error: LRM:3.10.2(24) The expected type for X'ACCESS, where X denotes an ***** aliased view of an object, must be a general access type, ***** Continuing 228 Result21 : Float := Zup (Float_Ptr'(Temperature'access)); -- OK 229 230 Result22 : Float := Zup (Temperature'Unchecked_Access); -- ERROR: Ambiguous * *****Error: LRM:8.6(31) Expression is ambiguous when interpreted as an ***** expression of the expected type Float, Returning first ***** interpretation * *****Error: LRM:3.10.2(24) The expected type for X'ACCESS, where X denotes an ***** aliased view of an object, must be a general access type, ***** Continuing 231 Result23 : Float := Zup (Float_Ptr'(Temperature'Unchecked_Access)); -- OK > Specifically: > Example 1 Example 2 > GNAT 3.13a: No error No error > Apex 3.0.2b: Error No error > Janus/Ada 3.1.2: No error Error > > Of these three, only Janus/Ada matches Tucker's proposed wording. (And given > it's market share, we probably can ignore it.) > > The reason some ACATS test is desperately needed here is exactly that the > compilers all differ in what they allow and reject. If we change the > language, then I would change the test(s) accordingly (and issuing them > after the AI is approved by WG9) -- but I think it is a crime to let > compilers vary all over the map here. Yes, whatever we decide on this, the ruling should not allow implementations to differ, and the ACATS should enforce the ruling. I would probably be willing to volunteer to write the test; let me know (if and when we get to that point). **************************************************************** From: Pascal Leroy Sent: Thursday, May 11, 2000 2:50 AM > I think the difference between pool-specific and general access types > should *not* be used to resolve these things, and the above wording > achieves that. Randy, is it really true that some compilers use the > pool-specific/general distinction to resolve these cases? Which ones? We do. Somebody was confused and considered that the second sentence of RM95 3.10.2(24) was a name resolution rule, which obviously it isn't. I'll fix this, as there is clearly a consensus that this information should not be used for name resolution. **************************************************************** From: Randy Brukardt Sent: Thursday, May 11, 2000 6:57 PM To bring the discussion back to Tuck's wording. In my original message, I had given an example where the prefix of the 'Access was overloaded. Gary and I, at least, agree that we don't want to try to resolve this expression, but I'm not sure how to get there. And Tuck's wording seems to assume that the prefix is not overloaded (which would break access to subprogram types). Here is my object example from my original posting: type Int_Ptr is access all Integer; type Char_Ptr is access all Character; type Float_Ptr is access all Float; function Zap (Val : Int_Ptr) return Float; function Zap (Val : Float_Ptr) return Float; function Zop return Int_Ptr; function Zop return Char_Ptr; Resultx : Float := Zap (Zop.all'access); This expression has a unique resolution if we use everything we know. But to allow it means giving up on the "single access type" wording, which we need to insure that 'access can't be used in contexts where no particular type is implied (i.e. type conversions). Tucker's wording (which I will repeat for those of us who've forgotten it already...:-): For an attribute_reference with attribute_designator Access (or Unchecked_Access -- see 13.10), the expected type shall be a single access type whose designated type covers the type of the prefix, or whose designated profile is type conformant with that of the prefix. So what is the type of the prefix (Zop.all) in the example above? It is either Integer *or* Character. One way to handle this is to interpret this a chicken-and-egg rule; if that's done, my example does in fact resolve and is legal. (By chicken-and-egg rule, I mean that we really don't know the answer; we simply apply all of the rules at once to get the answer. Resolution is very much like this anyway.) Note that the access to subprogram case already uses the designated profile of the expected access type to resolve the prefix (the second sentence of 3.10.2(2)). We certainly don't want to change that behavior. Of course, using "single access type" in this way is a real fudge (because we do allow sets of types as long as only one matches any possible interpretation of the prefix). But we need that to disallow 'access in contexts where a specific type can't be identified (such as type conversions). Gary has proposed "maybe an extra rule is needed to say that the prefix shall only have a single interpretation". However, that doesn't work for the access-to-subprogram case; that is specifically designed to allow overloaded prefixes. An example for that: procedure Foo (A : in Integer); procedure Foo (B : in Float); type Access_Single_Int_Proc is access procedure (A : in Integer); P : Access_Single_Int_Proc := Foo'access; -- OK. Foo'access is legal now, and any wording we adopt had better allow it to stay that way. A question for Tucker: is your wording intended to replace the entire paragraph? That is, including the second sentence, and the "never an implicit conversion" phrasing? I don't see a real problem with that, but it does extend the resolution still further. I guess I don't object to Tucker's rule, although the corner cases of it may be more work that they are worth. OTOH, I suppose I could agree not to test them in the ACATS. Randy. **************************************************************** From: Tucker Taft Sent: Thursday, May 11, 2000 7:17 PM Randy Brukardt wrote: > > > > Perhaps something like this would work for 3.10.2(2): > > > > > > Name resolution rules: > > > > > > For an attribute_reference with attribute_designator Access (or > > > Unchecked_Access -- see 13.10), the expected type shall be > > > a single access type whose designated type covers the type of > > > the prefix, or whose designated profile is type conformant > > > with that of the prefix. > > > > Thank you, Tucker. I tried to come up with wording today, and failed. > > The above sounds exactly right, if we want to make this language > > change. I suppose I could go along with this language change; I'm open > > to either choice at this point. > > On first glance, this looks pretty good. It clearly solves most of the > problems by leaving the "single access type" wording, which we need to avoid > using 'Access in type conversions. > > One question, though, how does this work if the prefix is overloaded? That > is, given the third example in my original message, is it legal or illegal > (and why?) Overloading seems OK in the prefix. After all, we already allow the prefix to be overloaded when creating an access-to-subp value. From an implementation point of view, you bubble up one or more "universal" access-to-type/profile interpretations, and then complain if you get all the way to the top and you still have any ambiguity. On the way back down, you check to see whether the access type ultimately chosen uniquely selects one interpretation of the prefix using only the type matching, and presuming it does, you then enforce the other legality rules. The current implementation of access-to-subp has to work pretty much the same way, since it is possible to via "use" clauses have so much ambiguity in the prefix that even knowing the specific access-to-subp type won't resolve it, and you need to report this fact on the way "down". If the above is confusing, I could provide some concrete examples. In any case, from my perspective, trying to outlaw overloading of the prefix is unnecessary. I think the proposed rule works even if the prefix is overloaded. **************************************************************** From: Robert Dewar Sent: Thursday, May 11, 2000 7:20 PM Tuck's wording seems fine to me, although I hesitate to label this as an expert opinion :-) Certainly it seems to take care of the case I was concerned about. So the only issue is whether this is troublesome from any point of view. **************************************************************** From: Tucker Taft Sent: Thursday, May 11, 2000 10:11 PM Randy Brukardt wrote: > > To bring the discussion back to Tuck's wording. > > In my original message, I had given an example where the prefix of the > 'Access was overloaded. Gary and I, at least, agree that we don't want to > try to resolve this expression, but I'm not sure how to get there. I don't see why you don't want to resolve this. > ... And > Tuck's wording seems to assume that the prefix is not overloaded (which > would break access to subprogram types). I admit that the wording *could* be interpreted that way, but that would be wrong ;-). The "shall be a single type" wording really is not very different from the usual name resolution rules. You can pretty much ignore the "single" part of the sentence, except for the added restriction of 8.6(27) disallowing use as the operand of a type conversion. The key thing is that there is a clearly specified amount of information that bubbles out of the construct. In the case of an aggregate, what bubbles out is that it is a composite non-limited object. In the case of an allocator, what bubbles out is that the designated type must cover the type given in the allocator. Note that with an allocator like new T, the possible access types include access-to-T as well as access-to-T0'Class where T0 in any ancestor of T. This whole group of possibilities needs to "bubble up" from the allocator. Allowing the prefix of 'Access to be overloaded simply makes the set of acceptable access types being bubbled up more complicated, but it still can be thought of as a "class" for the purposes of 8.6(27). And context has to pick just one of these access types, without getting any more information out of the attribute ref. Of course, there is not much more information that could be interesting, so the wording I proposed is not substantially different than simply saying: For an attribute_reference with attribute_designator Access (or Unchecked_Access -- see 13.10), the expected type shall be an access type whose designated type covers the type of -- NOTE: "single" omitted the prefix, or whose designated profile is type conformant with that of the prefix. Followed by a special rule that blah'access may not be an operand of a type conversion. In retrospect, most of the wording of 8.6(27) is unnecessary, other than the part disallowing use of these kinds of constructs as operands of type conversion or in contexts where any type in a class is allowed. The special wording is unnecessary because normal overloading resolution rules will require there be only one interpretation of the context that matches the type requirements bubbling up from the construct. The key point is we want the context to expect a particular type, not just specify some generic requirement for a type in some class, which might mean we have to search all accessible packages for a unique type that meets both the "bubbling up" requirements and the contextual requirements. So that is really all the word "single" is there for. It doesn't mean there is no overloading inside or outside the construct. Despite my earlier claims to the contary, the usual chicken-and-egg analysis is still necessary, e.g. in the case of allocators. For example, the following contextual overloading is legal even though the "single" wording applies to allocator resolution: type NT is new T with null record; procedure Q(X : access T'Class; Y : Integer); procedure Q(X : access NT'Class; Y : Float); ... Q(new NT, 2); -- allocator resolves to "access T'Class" > > Here is my object example from my original posting: > > type Int_Ptr is access all Integer; > type Char_Ptr is access all Character; > type Float_Ptr is access all Float; > > function Zap (Val : Int_Ptr) return Float; > function Zap (Val : Float_Ptr) return Float; > > function Zop return Int_Ptr; > function Zop return Char_Ptr; > > Resultx : Float := Zap (Zop.all'access); > > This expression has a unique resolution if we use everything we know. But to > allow it means giving up on the "single access type" wording, which we need > to insure that 'access can't be used in contexts where no particular type is > implied (i.e. type conversions). I don't agree we need to abandon the "single access type" wording. As mentioned above, the point of the "single ... type" requirement is that the context must not expect just any type in a class, it must instead expect particular types. For access types, I think that really just outlaws the use of type conversion. Even an expected type of "access T'Class" would be OK, since that is a particular, albeit anonymous, type. Other contexts that don't require particular types are things like the initializer for a named number, the bounds of an integer type definition, the condition of an IF statement, etc., none of which are relevant to access types. (In Ada 95, there are fewer of these contexts because places like the operand of 'Val have a particular type as their expected type, namely universal_integer. Of course numeric literals don't have the "single type" rule anyway, so this use of universal_integer is not relevant to this analysis.) > ... > > A question for Tucker: is your wording intended to replace the entire > paragraph? That is, including the second sentence, and the "never an > implicit conversion" phrasing? I don't see a real problem with that, but it > does extend the resolution still further. The "never an implicit conversion" rule is actually redundant with 4.1.4(6), so it is not strictly necessary to repeat it. However, we found it friendly to do so before, and we don't want to give the appearance of a change. So here is a way to retain it (and in fact, be more symmetrical in our redundancy ;-): For an attribute_reference with attribute_designator Access (or Unchecked_Access -- see 13.10), the expected type shall be a single access type whose designated type covers the type of the prefix, or whose designated profile is type conformant with that of the prefix. The prefix of such an attribute_reference is never interpreted as an implicit_dereference or parameterless function_call (see 4.1.4). The last sentence is bracketed in the AARM, since it is redundant with 4.1.4(6). > > I guess I don't object to Tucker's rule, although the corner cases of it may > be more work that they are worth. OTOH, I suppose I could agree not to test > them in the ACATS. I would be surprised that the corner cases would be harder to resolve. Of course, bugs are possible, but I would rather see a test case that exercises all of the crazy cases, and have someone object if they have real heartburn supporting it. I wouldn't normally feel this way, but since we are making this change to bring all the compilers into agreement in an area where they seem to have wandered off in different directions, let's go all the way. Here is a crazy case, for example, that we might as well include: type P is access procedure; type A is access Integer; procedure Z(X : P; Y : Integer); procedure Z(X : A; Y : Float); function F return P; function F return A; ... Z(F.all'access, 2); -- F.all'access resolves to type P. **************************************************************** From: Robert A Duff Sent: Friday, May 12, 2000 10:15 AM > In my original message, I had given an example where the prefix of the > 'Access was overloaded. Gary and I, at least, agree that we don't want to > try to resolve this expression, but I'm not sure how to get there. And > Tuck's wording seems to assume that the prefix is not overloaded (which > would break access to subprogram types). When I first read Tuck's wording, I interpreted it to mean that the prefix can be overloaded, and the designated type of the access type can be used to resolve it. The compiler has to consider all possible interpretations, and figure out the right one -- that's how overload resolution always works. For example, here's a plain-vanilla case of overload resolution: procedure P(X: Integer); procedure P(X: Boolean); function F return Integer; function F return Character; P(F); The RM says that the expected type for the actual parameter of P is the type of the formal. But there are *two* formals to consider -- one is Integer, one is Boolean. So we read the arcane mutterings in 8.6, and find out that we need to consider both. So the above resolves just fine. Tuck's new wording for 3.10.2.(2) should be read the same way. > Here is my object example from my original posting: > > type Int_Ptr is access all Integer; > type Char_Ptr is access all Character; > type Float_Ptr is access all Float; > > function Zap (Val : Int_Ptr) return Float; > function Zap (Val : Float_Ptr) return Float; > > function Zop return Int_Ptr; > function Zop return Char_Ptr; > > Resultx : Float := Zap (Zop.all'access); I think the compiler should be required to resolve the above. And I think Tuck's wording achieves that, if you pay attention to 8.6. The "type of the prefix" has to be interpreted as "the two possible types of the two possible prefixes", each considered separately. > A question for Tucker: is your wording intended to replace the entire > paragraph? That is, including the second sentence, and the "never an > implicit conversion" phrasing? I don't see a real problem with that, but it > does extend the resolution still further. I thought Tuck's wording replaced just the *first* sentence of 3.10.2(2). But the "never an implicit conversion" phrasing should be retained -- it is square-bracketed in the AARM, which indicates that it follows from something else. The actual rule is in 4.1.4(6). It seems to me that the second sentence is still needed, and we also need an anaogous sentence for the access-to-object case, now that we allow overloading of the prefix: If the expected type is an access-to-object type, then the expected type of the prefix is the designated type of the access type. Add the above after Tuck's wording, and then: "Similarly, [second sentence of existing RM para]." > I guess I don't object to Tucker's rule, although the corner cases of it may > be more work that they are worth. OTOH, I suppose I could agree not to test > them in the ACATS. I strongly believe we should test this sort of thing -- ESPECIALLY the corner cases. This is the sort of thing that can cause very real portability problems. I find it *very* distasteful to spend a lot of energy making good rules, and then turn around and say, "we don't really mean it". The *only* time we should agree to avoid testing something is when there's a pathology in the language, and we can't fix it for some reason. Pathologies are language bugs. We shouldn't call something a pathology just because it seems like a fairly rare combination of features, and/or is hard to implement. Compiler writers (that's many of us) tend to be far too willing to label something a pathology, in my opinion (which is why I'm ranting about this now ;-)). Besides, I don't see any particular implementation difficulty here; we're basically doing access-to-object the same way access-to-subprogram is already done. And we've already got some compilers that (naughtily) implement it that way! I say, if we're not willing to test what the rules say, then we've designed the wrong rules! **************************************************************** From: Robert A Duff Sent: Friday, May 12, 2000 1:14 PM Tucker mentioned to me this morning that the NOTE at RM-4.1.4(14) will be wrong if we adopt the new rule. That should be fixed, if a new RM is being produced. Also, the AARM-3.10.2(2.a) will be wrong. I don't know how Randy wants to deal with the AARM. If I were him, I would not modify the AARM annotations at all, but merely add a new annotation saying the above is obsolete. It's not really ARG's job to maintain the AARM, but I suspect Randy's tools will be able to turn it into a more modern formatting language more-or-less "for free". (Free speech *and* free beer.) ************************************************************* From: Randy Brukardt Sent: Friday, May 12, 2000 12:02 PM OK, merging Bob's and Tuck's suggestions, we get the following for the revised wording of the complete paragraph 3.10.2(2): For an attribute_reference with attribute_designator Access (or Unchecked_Access -- see 13.10), the expected type shall be a single access type whose designated type covers the type of the prefix, or whose designated profile is type conformant with that of the prefix. [The prefix of such an attribute_reference is never interpreted as an implicit_dereference or parameterless function_call (see 4.1.4).] If the expected type is an access-to-object type, then the expected type of the prefix is the designated type of the access type. Similarly, if the expected type is an access-to-subprogram type, then the expected profile of the prefix is the designated profile of the access type. Any objections or technical problems? If not, I'll rewrite the AI to use this wording. Then we can consider it at the next meeting. BTW, I've initiated a compiler survey in order to have a stronger justification for making this change. So far, most of the compilers reported are closer to the new wording than to the existing RM. ************************************************************* From: Tucker Taft Sent: Friday, May 12, 2000 3:01 PM > Any objections or technical problems? It is getting a bit verbose. Perhaps we could shorten the last two sentences to: The designated type/profile of the expected type of the attribute_reference is the expected type/profile for the prefix. ************************************************************* From: Robert A Duff Sent: Friday, May 12, 2000 3:52 PM > It is getting a bit verbose. Perhaps we could shorten the last two > sentences to: > > The designated type/profile of the expected type of the > attribute_reference is the expected type/profile for the prefix. I like it. And now that we have wording that says what we think it says, we can talk about whether we should change the language in this way. My first reaction to this issue was "No way! Rules are rules! Make all those evil compiler writers who did it wrong fix it. (Including us.)" But now I'm inclined to say we should make the change. I think it improves the language. Also, as Robert Dewar points out, some people are depending on this compiler bug, so we should probably declare it to be a non-bug. ************************************************************* From: Randy Brukardt Sent: Friday, May 12, 2000 6:05 PM > > It is getting a bit verbose. Perhaps we could shorten the last two > > sentences to: > > > > The designated type/profile of the expected type of the > > attribute_reference is the expected type/profile for the prefix. > > I like it. Well, I don't. I don't know quite what to make of the slashes. If I mentally replace them by "or", it makes more sense -- but then why not say that? The designated type or profile of the expected type of the attribute_reference is the expected type or profile for the prefix. > And now that we have wording that says what we think it says, we can > talk about whether we should change the language in this way. > > My first reaction to this issue was "No way! Rules are rules! Make all > those evil compiler writers who did it wrong fix it. (Including us.)" > > But now I'm inclined to say we should make the change. I think it > improves the language. Also, as Robert Dewar points out, some people > are depending on this compiler bug, so we should probably declare it to > be a non-bug. While I think the basic idea is a good one, I don't think we can get around the fact that this wording is an *extension* to the language. The behavior of existing compilers don't fully support Tucker's wording. With Bob's help, I've tested the two overloading examples (mine and Tucker's) on 4 popular compilers (well, 3 popular compilers and Janus/Ada. :-) Indeed, all four compilers choke on my example, even when qualified, presumably because they don't support overloading in the prefix (a couple of the compilers put out a message to that effect). [GNAT seems to have a bug here, as it seems to select one interpretation of the prefix, ignoring any others silently.] The access-to-subprogram type in Tucker's example seems to confuse matters. The compilers seem to prefer either the object or the subprogram prefix; but no compiler allows both. I've also found out from Joyce that the DDCI compiler in fact implements the RM rules. (It too has a bug and misses a couple of errors, but not the same ones as Rational Apex). So the compiler survey is now less clear cut. (I'm still waiting for responses from other compiler vendors.) The overloading implications of Tucker's wording may take some effort to get right, and may be quite difficult in some implementations. Moreover, it is a clear extension to practice in any compiler that I've got a result for. I would feel better with wording which did not require support for overloading resolution in the prefix of object'access. I'm not sure that such wording is possible. If we feel we have to have overloading resolution in the prefix to make this work (and I currently think we do), then I fear we have a clear extension -- we can't even rely on the behavior of current compilers to justify the change. In that case, the only reasonable choices are to confirm the RM (which Robert doesn't like for possibly legitimate reasons), or to make the change in Ada 0y and emasculate the ACATS test to leave only cases that neither conflict with the current RM or revised wording (which would leave Ada users with the portability problem for at least 5 more years). Both bad choices. ************************************************************* From: Tucker Taft Sent: Friday, May 12, 2000 6:47 PM I agree with Bob. I think we should make the change, and add a test to ACATS that does its best to get all compilers to handle the resolution of 'Access the exact same way. ************************************************************* From: Robert Dewar Sent: Friday, May 12, 2000 7:43 PM But the test could only be advisory pending WG9 accepting the relevant AI I suppose. ************************************************************* From: Robert A Duff Sent: Saturday, May 13, 2000 10:41 AM Randy proposes: > The designated type or profile of the expected type of the > attribute_reference is the expected type or profile for the prefix. That's sound fine, too. ************************************************************* From: Tucker Taft Sent: Monday, May 15, 2000 7:54 AM Randy Brukardt wrote: > ... > While I think the basic idea is a good one, I don't think we can get around > the fact that this wording is an *extension* to the language. The behavior > of existing compilers don't fully support Tucker's wording. I don't think this really is the issue. Yes it is certainly an extension. However, we have concluded that few compilers support the existing wording, and we recognize some clear problems with the wording as in the RM as far as functionality. It would never be appropriate to expect all compilers to magically implement some well-stated different rule, since the current behavior is due to a series of oversights or laxness during implementation. I suggest we ask implementors to evaluate the implementation difficulties of the general overloading solution. In my experience, it is usually easier to allow arbitrary overloading than to enforce particular restrictions. Furthermore, the kind of overloading we are talking about is very similar to the kind of overloading that occurs in many other constructs. Hence, I suggest we take what is the cleanest rule (which I feel is roughly where we are now in our wording), and run it up the flagpole. Trying to fit the wording to the existing behavior of some compilers is bound to produce a kludgier rule, and likely be harder for some compilers than others to get right. This seems like a lose-lose. Once we have more input from implementors, the ARG can decide whether to approve the change. The fact that it is an "extension" is not really relevant in my view, presuming we approve it and have a good test for it. Note that in Ada 83 we approved extending the character set from 128 to 256 characters, a much more significant change. Clearly any ACATS enforcement of a change like this, presuming it is approved, has to be phased in... ************************************************************* From: Robert Dewar Sent: Monday, May 15, 2000 10:26 AM <<> While I think the basic idea is a good one, I don't think we can get around > the fact that this wording is an *extension* to the language. The behavior > of existing compilers don't fully support Tucker's wording. >> Well lots of AI's in the past have been language extensions (to be honest) ************************************************************* From: Randy Brukardt Sent: Wednesday, May 31, 2000 4:56 PM I sent my super-duper ACATS test for this issue to the vendors whose compilers I don't currently have access to to get a better feel for where the majority of compiler's stand. Example 1 is the basic "use-of-the-prefix-type" resolution case. (This should fail given the RM wording and succeed given the change proposed in AI-235.) Example 2 is the test of a conflict between a general access type and a pool-specific access type. This should fail; there is no intent to change this. Example 3 is the resolution of an overloaded prefix. This should fail (trivially) given the RM wording and succeed given the change proposed in AI-235.) Example 4 is similar to example 3, but it uses the type of an additional parameter to resolve. This should have the same results as example 3. [I didn't provide Examples 3&4 to all of the vendors, so not all compilers have results for these cases.] Here is an updated list: Example 1 Example 2 Example 3 Example 4 GNAT 3.13a: No error No error Error* Error* Apex 3.0.2b: Error No error Error* Error* Janus/Ada 3.1.2: No error Error Error* Error* AverStar adacsrc 3.317: No error Error Error* Error* DDCI: Error Error* OcSystems 4.1: No error Error * Notes: GNAT 3.13a apparently resolves overloaded object'access prefixes by arbitrarily selecting the last overloaded routine as the solution. Thus some expressions resolve, and others do not. This seems to be a bug, it would be better to reject all such expressions. Janus/Ada 3.1.2 rejects object'access prefixes which cannot be uniquely resolved without context. (As I recall, allowing the use of some context for access-to-subprograms was very painful, but I don't know if the extension would be a problem.) It gets confused when object'access is overloaded with subprog'access. Apex 3.0.2b rejects object'access prefixes which cannot be uniquely resolved without context. It seems to prefer object'access over subprog'access when they both are overloaded, confusing Example 4. Averstar 3.317 rejects object'access prefixes which cannot be uniquely resolved without context. It seems to prefer subprog'access over object'access when they both are overloaded, confusing Example 4 (and exactly the reverse of Apex). DDCI's compiler almost matches the RM, but allows overloading between access-to-subprogram types and object types. ---- The Janus/Ada, Averstar, OcSystems, and GNAT compilers (and presumably the Aonix and Greenhills compilers as well) come close to Tucker's proposed wording. Janus/Ada and GNAT have some minor differences in handling overloading, and GNAT also fails the "general vs. pool-specific" issue, but these aren't significant. The Rational Apex and DDCI compilers come close to the existing RM wording, so they would have to change the most. But that would be painless to their users, while changing all of the others could very well be painful to their users. Note that no compilers tested handle the overloading cases properly (that is, as suggested by Tucker's wording). Randy. ************************************************************* From: Gary Dismukes Sent: Wednesday, May 31, 2000 7:43 PM A comment on part of the !discussion section: > To work around the problem caused by the original RM rule, a named access > type has to be introduced, so that it can be used in a qualified expression: > > function Do_It (Obj : Int_Ptr) return Boolean; > > if Do_It (Int_Ptr'(Value'Access)) then ... -- OK. > > But this is not quite equivalent, because the accessibility rules for > anonymous access types is different from named access types. Thus, the user > usually will have to change to using 'Unchecked_Access as well. What you say is true, but the above is a little confusing, because it's not necessary to change the type of the formal parameter. The formal can be left as "Obj : access Integer", only the actual in the call needs to be changed for this workaround. So I suggest deleting the function spec with the Int_Ptr parameter, and then you should clarify that it's the conversion implicit in the qualified expression that changes the accessibility semantics. (Of course, as long as the extra access type is declared at the same level as the call, then this workaround should have the same accessibility semantics, i.e., no access check needed, but it's obviously a bit messy and error-prone to have to declare a local access type.) ************************************************************* From: Randy Brukardt Sent: Wednesday, May 31, 2000 10:27 PM > So I suggest > deleting the function spec with the Int_Ptr parameter, OK; I didn't realize that would work (although it obviously does). > and then you should clarify that it's the conversion implicit > in the qualified expression that changes the accessibility semantics. This seems as confused as my original statement. The accessibility check is part of the 'Access attribute (3.10.2(28-29)), and its the expected type of the attribute that determines the check made. Using the qualified expression changes the expected type to the named type, and that changes the accessibility. There is an implicit conversion to the "original" weaker checks of anonymous access types when the qualified expression is converted, but that won't do anything interesting in this case. >(Of course, as long as the extra access type is declared at the same level as > the call, then this workaround should have the same accessibility > semantics, i.e., no access check needed, but it's obviously a bit > messy and error-prone to have to declare a local access type.) I changed the paragraph in question to: To work around the problem caused by the original RM rule, a named access type has to be introduced, so that it can be used in a qualified expression: if Do_It (Int_Ptr'(Value'Access)) then ... -- OK. But this is not quite equivalent, because the accessibility rules for anonymous access types is different from named access types. (The use of the qualified expression changes the accessibility check for the Access attribute from the anonymous type to the named type.) Thus, the user will have to declare an access type in the scope of each call, or will have to change to using 'Unchecked_Access. Does that meet your concern? (Since I forgot to check it in earlier, this will be in today's version of the AI.) ************************************************************* From: Tucker Taft Sent: Thursday, June 01, 2000 8:30 AM Looks good to me (modulo Gary's suggestion about the example). ************************************************************* From: Ed Schonberg Sent: Thursday, June 01, 2000 8:27 PM Randy's test now passes on gnat: nile{schonber}65: gnatmake -I../ c3a200x gcc -c -I../ c3a200x.adb gcc -c -I../ c3a200xa.adb gcc -c -I../ report.adb gnatbind -aO./ -aO../ -I- -x c3a200x.ali gnatlink c3a200x.ali nile{schonber}66: c3a200x ,.,. C3A200X ACVC 2.0 00-06-01 21:15:39 ---- C3A200X Check that 'Access and 'Unchecked_Access attributes can use the type of their prefix in resolving overloading.. ==== C3A200X PASSED ============================. This took about an hour of work, and added 50 lines to the front-end, so needless to say we find this a perfectly implementable rule (and furthermore one that will not force us to change all these overloaded prefixes in our own run-time!). ************************************************************* From: Pascal Leroy Sent: Tuesday, June 06, 2000 7:22 AM I have modified our compiler to implement AI-235: varenne$ c3a200x ,.,. C3A200X ACVC 2.2 00-06-06 14:06:02 ---- C3A200X Check that 'Access and 'Unchecked_Access attributes can use the type of their prefix in resolving overloading.. ==== C3A200X PASSED ============================. It took me a bit less than a day, and the version control system tells me that I have changed 272 lines (to be honest, these changes included fixing a bug in the handling of the access-to-subprogram case that I noticed while reading the code). So for us this was not a big change, even though we were originally quite close to the RM. I haven't run an entire ACVC yet, but I am noticing that we now fail test b3a2016, which is not surprising since this test checks RM95 3.10.2(2). It seems to me that vendors should be able to validate compilers which implement AI-235, and therefore that this test should be removed from the suite. I'd like to hear the ACAA's opinion on this. ************************************************************* From: Randy Brukardt Sent: Friday, June 16, 2000 6:21 PM Pascal said: > I haven't run an entire ACVC yet, but I am noticing that we > now fail test b3a2016, which is not surprising since this > test checks RM95 3.10.2(2). It seems to me that vendors > should be able to validate compilers which implement AI-235, > and therefore that this test should be removed from the > suite. I'd like to hear the ACAA's opinion on this. Randy responds (wearing my ACAA hat): It was obvious to me the B3A2016 would have to be changed, because as long as AI-235 is under consideration, testing cases that it might change (either way) is wrong. OTOH, the test includes some useful cases (and I had added several more useful cases more recently), and a B-Test is clearly needed along with a C-Test (assuming AI-235 passes as is). So I created a version of the test with all of the problematical cases commented out, and a variety of new cases. I thought it best to wait a while before issuing the test (to see if AI-235 would be changed again), so I went on vacation rather than actually issuing it. But I intend to do that next week. Under the ACAA rules, this action will reset the required date, so the new test won't be required until January 1st, 2001. Once WG9 approves AI-235, I'll issue an improved version of the C-Test (at least, the name has to be changed), and a revised version of the new B-Test (with the commented out cases replaced, either as "OK" or "Error", as needed). Randy Brukardt. ACAA Technical Agent. ************************************************************* From: Pascal Leroy Sent: Saturday, June 10, 2000 2:07 AM > !wording > > Replace 3.10.2(2) with: > For an attribute_reference with attribute_designator Access (or > Unchecked_Access -- see 13.10), the expected type shall be > a single access type whose designated type covers the type of > the prefix, or whose designated profile is type conformant > with that of the prefix. [The prefix of such an attribute_reference > is never interpreted as an implicit_dereference or parameterless > function_call (see 4.1.4).] The designated type or profile of the > expected type of the attribute_reference is the expected type or > profile for the prefix. I believe there is a serious problem with this wording. It seems to me that we have lost the ability to use 'Access as a controlling parameter of a dispatching call. Essentially, the changes that we did in AI 127 should have been taken into account when writing the wording section for AI 235. Consider the following code fragment: type T is tagged null record; function F (X : access T) return Boolean; X : T; Y : T'Class := X; Z : Boolean := F (Y'Access); It appears that the attribute Access in the declaration of Z is illegal according to the new wording. The expected type for Y'Access is the anonymous access type access T, and the designated type T does not cover the type of the prefix, T'Class, so the new 3.10.2(2) makes the attribute illegal. We don't even get as far as looking at RM95 8.6(22-25). ************************************************************* From: Randy Brukardt Sent: Friday, June 16, 2000 6:58 PM Yes, I agree. AI-127 is part of the corrigendum, so it has priority here. Fixing this wording is very hard (which probably why you didn't attempt it!). > Consider the following code fragment: > > type T is tagged null record; > function F (X : access T) return Boolean; > > X : T; > Y : T'Class := X; > Z : Boolean := F (Y'Access); > > It appears that the attribute Access in the declaration of Z > is illegal according to the new wording. He-he: it is illegal according to *any* wording, original, corrigendum, or AI-235. Because Y isn't aliased. :-) I assume you meant: Y : aliased T'Class := X; > The expected type for Y'Access is the anonymous access type access T, > and the designated type T does not cover the type of the prefix, T'Class, > so the new 3.10.2(2) makes the attribute illegal. We don't even get as > far as looking at RM95 8.6(22-25). I don't know what 8.6 has to do with it. The change for AI-127 (according to the corrigendum) is in 3.10.2(27) (with a small change to 3.10.2(24) to define @i): * If @i is a named access type and @i is a tagged type, then the type of the view shall be covered by @i; if @i is anonymous and @i is tagged, then the type of the view shall be either @i'Class or a type covered by @i; if @i is untagged, then the type of the view shall be @i, and @i's designated subtype shall either statically match the nominal subtype of the view or be discriminated and unconstrained; The change to 3.10.2(2) makes most of this unnecessary; it just echoes the resolution rule. (We do need the untagged part.) The best fix I can come up with is (but it's incredibly awkward): Replace 3.10.2(2) with: For an attribute_reference with attribute_designator Access (or Unchecked_Access -- see 13.10), the expected type shall be a single access type whose designated type covers the type of the prefix, or, if the type of the prefix is D'Class, whose designated type is D, or whose designated profile is type conformant with that of the prefix. [The prefix of such an attribute_reference is never interpreted as an implicit_dereference or parameterless function_call (see 4.1.4).] The designated type or profile of the expected type of the attribute_reference is the expected type or profile for the prefix. With this scheme, we'd probably be best off leaving 3.10.2(27) alone (we still need the rule about named vs. anonymous access types, along with the untagged type rule). I don't think we want to try to use whether or not the type is anonymous in resolution, even though it still affects legality. We can't name the type D in 3.10.2(2) like we did in 3.10.2(27), because access-to-subprogram types also come through 3.10.2(2), and they don't have a designated type. I'd prefer to use words for the "D'Class" garbage, but I can't find any that mean what I need: "...covers the type of the prefix or is the xxxx type of the prefix if the prefix has a classwide type, or whose...". What the heck *is* the name for the type represented by D in D'Class for a classwide type? The closest I can come is "specific" type, but I don't think that is right. Perhaps there isn't one, but perhaps there should be? *************************************************************