!standard 4.1.4(6) 06-05-11 AC95-00129/01 !class confirmation 06-05-11 !status received no action 06-05-11 !status received 06-04-12 !subject Resolving the prefix of an attribute !summary !appendix From: Randy Brukardt Date: Wednesday, April 12, 2006 9:30 PM I was working on a bug report on Janus/Ada, and cannot seem to find a clear answer to the above question. Specifically, the general rules for attributes in 4.1.4(6) only talk about a couple of special cases for the prefix (specifically, when the prefix has an implicit dereference or is a call). That makes sense, since the various attributes have quite different requirements on the prefix. However, the specific kinds of prefixes are described in "Static Semantic" rules. So it is not clear what precisely is the item being resolved to. I didn't find anything in 8.6 that covers this, either. This matters because a number of name resolution rules are conceivable, and they give different results in some boundary cases. Consider 'Valid (since this is what I was working on when I ran into the question) [13.9.2(2)]: For a prefix X that denotes a scalar object [(after any implicit dereference)], the following attribute is defined: So, given this, how is X resolved? I can imagine various rules: 1) The prefix has to resolve without using any information about the attribute designator; 2) The prefix has to resolve to an object of any kind; 3) The prefix has to resolve to a scalar object (or access to scalar object). (1) would be rather hard to implement, since things that normally wouldn't be considered at the same time (exceptions, types, labels, etc.) because they're not overloadable would have to be considered. Most of the time, you couldn't tell between (2) and (3), but it's possible to write a program that can tell: function Get_It return Integer is ... function Get_It return Rec is ... if Get_It'Valid then -- ??? Get_It'Valid would be legal if the rule is (3), but not if it is (2) (it would be ambigious in that case). [For the record, Janus/Ada used (3), but it was broken in obscure cases because the routine I used was expecting the caller to prune the tree. (Which only proves that you shouldn't mess with other people's code...) I was changing it to use a more general routine which would effectively implement (2), and I started to wonder which was right. And no answer was forthcoming...] I lean toward (2) for various reasons (Bob likes to say that the resolution rules shouldn't be too smart). Note that there are plenty of other attributes with similar issues; consider 'Tag, 'Length, 'Constrained, etc. Even 'Access has the issue (does "aliasedness" enter into resolution? I think we decided it didn't, but I'm not sure on what basis). **************************************************************** From: Robert A. Duff Date: Thursday, April 13, 2006 7:09 AM > So, given this, how is X resolved? I can imagine various rules: > 1) The prefix has to resolve without using any information about the > attribute designator; > 2) The prefix has to resolve to an object of any kind; > 3) The prefix has to resolve to a scalar object (or access to scalar > object). I believe 1 and 2 are equivalent, because all the non-object things are non-overloadable. I'm quite sure the intent is (1) (or, equivalently, (2)). > (1) would be rather hard to implement, since things that normally wouldn't > be considered at the same time (exceptions, types, labels, etc.) because > they're not overloadable would have to be considered. No, the non-overloadability is what makes it easy. If you say X'Valid, and there is an exception called X, and it is directly visible, then it is the _only_ thing called X that is directly visible. So you can implement (1), which resolves X to that exception, and then declare it illegal because you require an object. Or, you can implement (2), which says "no interpretations". Either way, it's illegal. > Most of the time, you couldn't tell between (2) and (3), but it's possible > to write a program that can tell: > > function Get_It return Integer is ... > function Get_It return Rec is ... > > if Get_It'Valid then -- ??? > > Get_It'Valid would be legal if the rule is (3), but not if it is (2) (it > would be ambigious in that case). It is ambiguous. > [For the record, Janus/Ada used (3), but it was broken in obscure cases > because the routine I used was expecting the caller to prune the tree. > (Which only proves that you shouldn't mess with other people's code...) I > was changing it to use a more general routine which would effectively > implement (2), and I started to wonder which was right. And no answer was > forthcoming...] GNAT complains: eg.adb:9:07: ambiguous prefix for "Valid" attribute for this example: procedure Eg is function Get_It return Integer is begin return 1; end; type Rec is null record; function Get_It return Rec is begin return (null record); end; begin if Get_It'Valid then null; end if; end Eg; > I lean toward (2) for various reasons (Bob likes to say that the resolution > rules shouldn't be too smart). I lean toward (1). ;-) I think it follows from the fact that we never say anything about the expected type (or expected profile) of these prefixes (except for the special cases in 4.1.4(6)). All the rules are under "Static Semantics". That's something of a cheat, though. I suspect there are some rules for various attributes that are (intended to be) Resolution rules, but we wanted to keep the rules for each attribute together. I believe we knew this was wrong at the time, and we deliberately placed style/readability of the RM above strict correctness. **************************************************************** From: Randy Brukardt Date: Wednesday, April 12, 2006 8:49 PM ... > > So, given this, how is X resolved? I can imagine various rules: > > 1) The prefix has to resolve without using any information about the > > attribute designator; > > 2) The prefix has to resolve to an object of any kind; > > 3) The prefix has to resolve to a scalar object (or access to scalar > > object). > > I believe 1 and 2 are equivalent, because all the non-object things are > non-overloadable. Humm, I had thought that there was some issue with use clauses that could get exceptions and the like into the mix, but perhaps not. In any case, subprograms are overloadable. (2) would allow resolving: Something'Valid where Something names both a procedure and a function, as only the function intrepreted as a function call would be an object. But (1) would not let you get to trying the function call; there would be no basis to discard the procedure. (1) seems wider than is needed in any other case, so it requires special code to implement. I suppose I can just ignore that and wait for the bug report (as Tucker has said in the past), but it's not the most comfortable solution. > I'm quite sure the intent is (1) (or, equivalently, (2)). Well, (1) and (2) aren't equivalent; they may be more similar than I was thinking, but they're not the same. ... > I lean toward (1). ;-) > > I think it follows from the fact that we never say anything about the expected > type (or expected profile) of these prefixes (except for the special cases in > 4.1.4(6)). All the rules are under "Static Semantics". I can buy that, but then there are complications (like making the example I gave above illegal). > That's something of a cheat, though. I suspect there are some rules for > various attributes that are (intended to be) Resolution rules, but we wanted > to keep the rules for each attribute together. I believe we knew this was > wrong at the time, and we deliberately placed style/readability of the RM > above strict correctness. Well, we clearly went out of our way to define Name Resolution Rules for 'Access, so that argues for your interpretation. But then there can be no grey areas: the prefix is resolved using no context whatsoever (even thought that is hard) for all attributes other than 'Access and 'Unchecked_Access. I don't think we can cheat about what are and are not resolution rules, because it really does affect the legality of some programs. This isn't an area where its OK for implementations to differ. **************************************************************** From: Pascal Leroy Date: Thursday, April 20, 2006 2:49 AM I have always assumed that (1) was the intent of the RM, but I agree that the words could be clearer. ****************************************************************