!standard 3.10.2(7/2) 11-03-04 AI05-0235-1/04 !standard 3.10.2(19.2/3) !reference AI05-0142-4 !class Amendment 10-11-18 !status Amendment 2012 11-03-04 !status ARG Approved 5-0-3 11-02-19 !status work item 10-11-18 !status received 10-11-15 !priority Low !difficulty Easy !subject Accessibility of explicitly aliased parameters !summary (1) The contradiction is resolved by added "unless otherwise specified" to 3.10.2(7/2). (2) Explicitly aliased parameters have special accessibility only within the return statement of a function; otherwise, they have the same accessibility as "normal" parameters. !question (1) The last sentence of 3.10.2(7/2) says "A parameter of a master has the same accessibility level as the master." Besides being vague, this conflicts with the 3.10.2(13.3/3) added by AI05-0142-4: "The accessibility level of an explicitly aliased (see 6.1) formal parameter in a function body is determined by the point of call (which is the same level that the return object ultimately will have)." The level surely cannot be both at the same time. Which is intended? (The second.) (2) Consider: type A_T is access all T; P : A_T; function F (L : aliased T) return Natural is begin P := L'access; -- Static check succeeds. ... end F; Based on the wording of 3.10.2(19.2/3), it appears that the static check succeeds here, as L is considered to have the "master that elaborated the function body of F", and that is the same master that elaborated A_T. Is this right? (No.) !wording Modify the last sentence of 3.10.2(7/2) and add the following AARM notes: {Other than for an explicitly aliased parameter, a}[A] {formal} parameter of [a master] {a callable entity} has the same accessibility level as the master {representing the invocation of the entity}. AARM To Be Honest: We use "invocation of the entity" as a master is formally an execution of something. But we mean this to be interpreted statically (for instance, as the body of the subprogram) for the purposes of computing "statically deeper than" (see below). AARM Ramification: Note that accessibility can differ depending on the view of an object (for both static and dynamic accessibility). For instance, the accessibility level of a formal parameter may be different than the accessibility level of the corresponding actual parameter. This occurs in other cases as well. AARM Reason: We define the (dynamic) accessibility of formal parameters in order that it does not depend on the parameter passing model (by-reference or by-copy) as that is implementation defined. Otherwise, there would be a portability issue. End AARM Notes. Replace 3.10.2(19.2/3) by * Inside a return statement that applies to a function F, when determining whether the accessibility level of an explicitly aliased parameter of F is statically deeper than the level of the return object of F, the level of the return object is considered to be the same as that of the level of the explicitly aliased parameter; for statically comparing with the level of other entities, an explicitly aliased parameter of F is considered to have the accessibility level of the body of F. * For determining whether a level is statically deeper than the level of the anonymous access type of an access result of a function, when within a return statement that applies to the function, the level determined by the point of call is presumed to be the same as that of the level of the master that elaborated the function body. AARM To Be Honest: This rule has no effect if the previous bullet also applies (that is, the "a level" is of an explicitly aliased parameter). [This latter bullet is from AI05-0051-1; it was replaced by early versions of the first bullet, but eventually they diverged and the point of this bullet was lost.] !discussion (1) The wording of 3.10.2(7/2) is quite vague. It is clear that it doesn't make sense for this rule to apply to actual parameters, so it is only talking about formal parameters of a callable entity. (2) Allowing cases like this would require the dynamic check to catch problems, and that would imply some overhead (once per function call, not per parameter) to pass an accessibility level. That's necessary because we need to detect local calls where local objects might have been passed. That overhead doesn't seem to buy us anything, so we change the wording to eliminate it (other than in the cases covered by AI05-0234-1). !corrigendum 3.10.2(7/2) @drepl @xbullet @dby @xbullet !corrigendum 3.10.2(19/2) !comment Really in the conflict file. @dinsa @xbullet @dinss @xbullet, when determining whether the accessibility level of an explicitly aliased parameter of @i is statically deeper than the level of the return object of @i, the level of the return object is presumed to be the same as that of the level of the explicitly aliased parameter; for statically comparing with the level of other entities, an explicitly aliased parameter of @i is considered to have the accessibility level of the body of @i.> @xbullet !ACATS Test This will be tested as part of the tests for AI05-0142-4. !ASIS No effect on ASIS. !appendix [The following is part of the discussion of AI05-0234-1 - Editor.] From: Steve Baird Sent: Monday, November 15, 2010 4:53 PM >... the language is very clear that the dynamic accessibility of such >a parameter is that of the actual object, and we definitely don't want >to have to pass that accessibility with all reference parameters. I'm not disagreeing with you because I see the argument: A dynamic accessibility level is a property of an object (as opposed to a view of an object) and a by-reference parameter doesn't introduce a new object - just a view of an existing object. But how do you reconcile this with 3.10.2(7/2): A parameter of a master has the same accessibility level as the master. ? **************************************************************** From: Randy Brukardt Sent: Monday, November 15, 2010 5:12 PM > But how do you reconcile this with 3.10.2(7/2): > A parameter of a master has the same accessibility level > as the master. > ? I can't, because out of context this doesn't make any sense at all. Masters don't have parameters; a master is a execution or evaluation of something (typically a statement), so I'm not quite sure what this is referring to. In context, it appears to be talking about parameters of declarations, but that doesn't make much sense either with this particular wording. I presume this is intended to do two things: define the *static* accessibility of parameters, and define the *dynamic* accessibility of by-copy parameters, but it is badly botched. Besides the by-reference case, it also is confused with access parameters that have some other accessibility defined (either that of the passed-in entity or "deeper than anything else"). This wording makes no sense for dynamic accessibility (with which it is associated), period. I would prefer to invoke the Duff rule on this one (the ARG is not in the business of answering questions that no one - other than ARG members musing around - has asked). But perhaps there is really something wrong here (not surprising, almost everything about accessibility is screwy in one way or another). **************************************************************** From: Tucker Taft Sent: Monday, November 15, 2010 5:37 PM Dynamic accessibility level *can* vary depending on the "view." Parameters in general are treated like local variables, even when of a type that requires pass by reference. The one exception is explicitly aliased parameters, where they are guaranteed to live at least as long as the return object. Similarly, even if an access discriminant is initialized to designate a global variable, the dynamic accessibility level of a dereference of the access discriminant is (generally) determined by the dynamic accessibility level of the enclosing object. So dynamic accessibility levels do vary according to the view. **************************************************************** From: Randy Brukardt Sent: Monday, November 15, 2010 5:25 PM ... > As far as the "static" check, I'll need Randy to give an example of > what he has in mind there. > I don't see how the value of the tag can possibly affect the static > check. Maybe I'm confused, but in the examples that Steve showed, the accessibility check was against the level of the expression, not the level of the type. That's a check that you cannot make normally at compile-time, as you would fail an accessibility check in normal cases. For example, assuming T is a tagged non-limited type, and TT is an extension of it at the same level: function Fooey (P : in TT; ...) return T'Class is begin if ... then return T'Class(P); -- OK in Ada 95 and Ada 2005 else ... end if; end Fooey; This return statement is legal in Ada 2005. There would be an accessibility check on the tag of TT, but it would staticly be OK. Now further presume that TT has an access discriminant. If we had directly returned the object TT, we would have needed an accessibility check on the object. In that case, the static accessibility check would have failed (we assume that P is local for this purpose). However, if we didn't have that static accessibility check, then we would have to use the accessibility of the actual object, which would have to be passed it (adding overhead). The only reason we don't need that overhead is because we have the static check that fails. Now, in the classwide case, we have *only* a runtime check, because in general we know nothing about the tag until runtime. That means that unless we add some sort of wording about the static check to the dynamic case, we have a distributed overhead in that every reference parameter would have to pass a dynamic accessibility level (in particular, that would be needed for all tagged parameters). Note that the check you described would always pass if Fooey was called with a library-level actual parameter, but should fail if called with a local actual parameter. That's what we have to avoid. **************************************************************** From: Tucker Taft Sent: Monday, November 15, 2010 5:48 PM > Now further presume that TT has an access discriminant. If we had > directly returned the object TT, we would have needed an accessibility > check on the object. In that case, the static accessibility check > would have failed (we assume that P is local for this purpose). > However, if we didn't have that static accessibility check, then we > would have to use the accessibility of the actual object, which would > have to be passed it (adding overhead). The only reason we don't need > that overhead is because we have the static check that fails. The dynamic accessibility level of a parameter, even if passed by reference, is like that of a local variable. Just think what happens when you take 'Access of a tagged parameter in Ada 95 and pass it as an access parameter. It gets a run-time accessibility level that makes it look like a local variable. The new "aliased" parameters are a bit different, in that they promise to live at least as long as the return object, so this example should be fine, even in Ada 2012. > Now, in the classwide case, we have *only* a runtime check, because in > general we know nothing about the tag until runtime. That means that > unless we add some sort of wording about the static check to the > dynamic case, we have a distributed overhead in that every reference > parameter would have to pass a dynamic accessibility level (in > particular, that would be needed for all tagged parameters). Again, the "dynamic" accessibility level of a parameter is "local" even if the actual parameter is a global object. > Note that the check you described would always pass if Fooey was > called with a library-level actual parameter, but should fail if > called with a local actual parameter. That's what we have to avoid. In cases like this, the accessibility level of an access discriminant is the same as the enclosing object, and that is "local" since it is a parameter. That means you don't need to pass anything in, and it will fail the run-time check if the actual object has access discriminants, even if the actual object is a global object. I think the net effect is that the "static" check you were mentioning is *already* a part of the "dynamic" check, since parameters lose their "real" accessibility level and take on the accessibility of a local variable. **************************************************************** From: Randy Brukardt Sent: Monday, November 15, 2010 5:52 PM > Dynamic accessibility level *can* vary depending on the "view." > Parameters in general are treated like local variables, even when of a > type that requires pass by reference. This is an oxymoron. Views are static properties that do not have any effect on dynamic properties. It doesn't make any sense. Beyond that, the one place in the standard that gives some credence to this view is clearly wrong, in that it is contradicted later in the same clause when access parameters are discussed. We never actually decided the question of whether by-reference parameters are objects in their own right, or whether they are just views of the actuals. It appears that we will need to do something on this line (either that, or fix up the wording to make sense). > The one exception is > explicitly aliased parameters, where they are guaranteed to live at > least as long as the return object. > > Similarly, even if an access discriminant is initialized to designate > a global variable, the dynamic accessibility level of a dereference of > the access discriminant is (generally) determined by the dynamic > accessibility level of the enclosing object. The accessibility is that of the access discriminant (which is that of the enclosing object). So what? I don't see your point here. > So dynamic accessibility levels do vary according to the view. Well, that simply doesn't make sense in the Ada model. Of course, nothing else about accessibility makes sense, either, so perhaps we can get away with it. But if that is what we want, it needs to be clearly explained in the AARM, and it is not. Remember that "view of" can automatically be appended to static semantic rules, but not to dynamic rules. If you mean that, you had better say so. Yes, I see these rules are defined in "Static semantics", but that makes no sense for a dynamic value. Accessibility is still badly defined. What else is new. **************************************************************** From: Bob Duff Sent: Monday, November 15, 2010 6:11 PM > > But how do you reconcile this with 3.10.2(7/2): > > A parameter of a master has the same accessibility level > > as the master. > > ? I didn't see the above-quoted message from Steve. Tucker said in another message that dynamic accessibility is a view property. I agree -- it has to be that way, because by-ref and by-copy are (sometimes) impl-def, and we don't want the semantics to differ (other than the essential difference in aliasing). I realize we're talking about tagged types in this conversation, but I'm just saying in general, passing something by ref shouldn't cause differences in accessibility level and so forth. > I can't, because out of context this doesn't make any sense at all. > Masters don't have parameters; a master is a execution or evaluation > of something (typically a statement), so I'm not quite sure what this is > referring to. It's talking about a master that is the execution of a procedure body, and the (formal) parameters of that. These are the plain old run-of-the-mill masters we got from Ada 83 -- all these "little" masters like statements were added since then. **************************************************************** From: Steve Baird Sent: Monday, November 15, 2010 6:31 PM Thanks to Tuck and Bob for straightening that one out. Ignoring new-fangled explicitly aliased parameters, a parameter pretty much behaves like a local with respect to accessibility. In most cases, one is more likely to arrive at the right answer if you go back to the RM and read the relevant wording instead of relying on internalized "I'm sure I remember it works this way" knowledge. In the case of accessibility rules, however, every rereading is an opportunity to get confused all over again. **************************************************************** From: Randy Brukardt Sent: Monday, November 15, 2010 6:35 PM ... > > > But how do you reconcile this with 3.10.2(7/2): > > > A parameter of a master has the same accessibility level > > > as the master. > > > ? > > I didn't see the above-quoted message from Steve. Steve sent it just to me, not sure if that was by accident or on purpose, but since I wanted to get the Tucker and Bob take on it, I replied to the list of names. > Tucker said in another message that dynamic accessibility is a view > property. I agree -- it has to be that way, because by-ref and > by-copy are (sometimes) impl-def, and we don't want the semantics to > differ (other than the essential difference in aliasing). I realize > we're talking about tagged types in this conversation, but I'm just > saying in general, passing something by ref shouldn't cause > differences in accessibility level and so forth. > > > I can't, because out of context this doesn't make any sense at all. > > Masters don't have parameters; a master is a execution or evaluation > > of something (typically a statement), so I'm not quite sure what > > this is referring to. > > It's talking about a master that is the execution of a procedure body, > and the (formal) parameters of that. These are the plain old > run-of-the-mill masters we got from Ada 83 > -- all these "little" masters like statements were added since then. It would be nice if this wording said that. Especially the word "formal", in which case it makes at least some sense. "A {formal} parameter of {the entity that} a master {is executing} has the same accessibility level as the master." Or something like that. Plus we need an exception for access parameters (because this rule surely doesn't not apply to them), and for explicitly aliased parameters. So "{Unless otherwise defined, } a {formal} parameter of {the entity that} a master {is executing} has the same accessibility level as the master." And we also need an AARM note to explain that. "AARM Ramification: Note that accessibility can differ depending on the view of an object (for both static and dynamic accessibility). In addition to the formal parameter case above, similar effects occur for the entities designated by access discriminants." "AARM Reason: We define the (dynamic) accessibility of formal parameters in order that it not depend on the parameter passing model (by-reference or by-copy) as that is implementation defined. Otherwise, there would be a portability issue." Or something like that (not sure we really want to list out examples, there may be more). Since we never actually say "dynamic accessibility in the standard, I put that in parens in the notes. P.S. Note that my original concern probably still exists for explicitly aliased parameters used in an allocator, although I doubt anyone will ever write a test to check that case. ;-) **************************************************************** From: Bob Duff Sent: Monday, November 15, 2010 6:43 PM > Or something like that. Plus we need an exception for access > parameters (because this rule surely doesn't not apply to them), and > for explicitly aliased parameters. So I mostly agree with your message, but I don't see the problem for access parameters. Are you talking about the parameter itself, or what it designates? "X: access T", the accessibility level of X is not relevant, since it's not aliased, so X'[Unchecked_]Access is illegal. The accessibility level of X.all is dynamic, but X.all is not a parameter so the rule we're talking about doesn't apply. The new aliased parameters may well need more thought. **************************************************************** From: Randy Brukardt Sent: Tuesday, November 16, 2010 12:23 AM > > Or something like that. Plus we need an exception for access > > parameters (because this rule surely doesn't not apply to them), and > > for explicitly aliased parameters. So > > I mostly agree with your message, but I don't see the problem for > access parameters. Are you talking about the parameter itself, or > what it designates? "X: access T", the accessibility level of X is > not relevant, since it's not aliased, so X'[Unchecked_]Access is > illegal. The accessibility level of X.all is dynamic, but X.all is > not a parameter so the rule we're talking about doesn't apply. I suppose you are right. > The new aliased parameters may well need more thought. They don't need "more thought", they have their own accessibility rule *(3.10.2(13.3/3)). I wasn't aware of this older blanket rule, or I would have added wording to repeal it in that case. They probably need "more thought" for AI05-0234-1, because I'd expect that the static/dynamic case would come up for allocators (as Tucker points out, they have to pass a return statement). BTW, it seems that we really want formal by-reference parameters to be a new object that happens to share memory with the old object. Besides this accessibility rule (where claiming that dynamic accessibility is a view property is unappealing), we also had similar issues with the values of representation aspects like 'Size and 'Alignment. We surely don't want to have to pass those along with parameters just so we can report them accurately. (I recall we decided that wasn't necessary with some phony hand-waving.) I wouldn't be surprised if this keeps coming up until we finally give in and change the definition... **************************************************************** From: Randy Brukardt Sent: Thursday, November 18, 2010 8:48 PM I had an action item to look for problems involving explicitly aliased parameters with these examples. First of all, for procedures, there is no special accessibility for these parameters (nor special checks on calls). So I'll only consider function calls. The accessibility rule for functions is: (3.10.2(13.3/3)) The accessibility level of an explicitly aliased (see 6.1) formal parameter in a function body is determined by the point of call (which is the same level that the return object ultimately will have). There is also a static rule, but since this is a purely dynamic check, it is irrelevant. Next, for return statements, an explicitly aliased parameter will always pass the accessibility check. (That's the whole point of this definition, the checks at the call site, etc.) That clearly includes this new check, so there is nothing further to think about there. That even includes an allocator for an anonymous access return type. So the question boils down to whether there can be a problem with an allocator. That would look something like: function F (L : aliased T) return Natural is begin P := new T'Class(L); ... end F; (This is not the intended usage of such parameters, but since it is possible, we have to consider it.) Whether the check would succeed or fail would depend upon where the type of P was declared. If P is local, the check would always succeed. If P's type is declared outside of F, whether the check would succeed might depend on where the call originated. For instance, if P is library-level, then a library-level call to F could succeed, while a nested call would fail. This would seem to have a small amount of overhead, but it is once per function (not per parameter), and is only needed in functions with aliased parameters. So that doesn't seem to be a major problem (although it is annoying). This is the case that the static check was intended to avoid, although it is not clear to me that it succeeds anyway. (If the function was elaborated at library level, one would expect the above to pass the static check given 3.10.2(19.3/3), and then the dynamic check would still be needed.) So, for now I don't see any need to change anything here. **************************************************************** From: Tucker Taft Sent: Thursday, November 18, 2010 8:58 PM > function F (L : aliased T) return Natural is > begin > P := new T'Class(L); > ... > end F; > > (This is not the intended usage of such parameters, but since it is > possible, we have to consider it.) > > Whether the check would succeed or fail would depend upon where the > type of P was declared. If P is local, the check would always succeed. > If P's type is declared outside of F, whether the check would succeed > might depend on where the call originated... I don't think this is worth the trouble. I suggest we treat these exactly like local variables except when checking the accessibility on a return statement. > So, for now I don't see any need to change anything here. Seems to me we want it to fail if P's type is non-local, and L has any access discriminants. **************************************************************** From: Randy Brukardt Sent: Thursday, November 18, 2010 9:24 PM I agree in this case, but the issue is that this is exactly what is required in the normal case: type A_T is access all T; P : A_T; function F (L : aliased T) return Natural is begin P := L'access; -- Static check succeeds. ... end F; So there is no extra overhead here for the access discriminant check; it already exists. The more interesting question is whether we intended that or we just screwed up the rules. My recollection (and the start of this entire thread) was that we had intended the static check to prevent such cases, so that no dynamic check would ever be needed. But it clearly doesn't (A_T and F are elaborated by the same master, so the static accessibility has to pass, but if the call to F is from a nested scope, a local object could be passed to the parameter, so the dynamic check would fail). I think we were trying to represent the half level between the function and it's declaration (that is, the parameter should be less local than a local object, but more local than anything declared where the function is), but we screwed up the wording. One possible fix for the normal case would be to give up on the special static accessibility outside of return statements. We've already done that partway, and we could just forget the whole thing. But it would be better to get it right and accurately reflect the half-level. But that doesn't help for the access discriminant check, because there is no static accessibility to help us. And I would be really against the *dynamic* accessibility depending on where an entity is used -- I don't have a clear idea of how that could reasonably be implemented. Only global variables come to mind, and that is awful. I can't think of any case currently where we would generate different code deep in an expression tree depending on context (it sometimes happens at the top-level for optimization, but I don't think it ever happens inside of a tree). What a tangled web of accessibility we weave... **************************************************************** From: Tucker Taft Sent: Thursday, November 18, 2010 9:55 PM ... > So there is no extra overhead here for the access discriminant check; > it already exists. Sorry, I am confused. You say the static check succeeds above. I would have said it failed. As far as the access discriminant check, the interesting case is when the aliased parameter is of a class-wide type, and we don't know until run-time whether there is an access discriminant. So the case of interest is: function F (L : aliased T'Class) return Natural is begin P := new T'Class(L); return 2; end F; I would say this should fail if L has any access discriminants, independent of the actual parameter's accessibility. We aren't passing an accessibility level along with "aliased" parameters, so I don't see how we could know the "true" accessibility level of the actual parameter anyway. The point of aliased parameters is that a reference to some part of the parameter can be returned from the function. In other contexts, they behave just like "regular" parameters (except that they are aliased, of course). I don't really follow the rest of this argument... **************************************************************** From: Randy Brukardt Sent: Thursday, November 18, 2010 10:33 PM > Sorry, I am confused. You say the static check succeeds above. I > would have said it failed. Why do you say that? Maybe it *should* have failed, but that doesn't appear to be the case. For the static check, 3.10.2(19.3/3) says in part: ...for statically comparing with the level of other entities, the level of the return object of F is considered to be the same as that of the master that elaborated the function body of F. The master that elaborated A_T and the master that elaborated F are the same, so I can't see any reason for the static check to have failed in this example. Are you saying this wording is not what we intended? That's surely possible; I was trying to figure out the consequences assuming that it was correct, but perhaps that was a waste of time. (I note this wording seems to have lost the fact that it is defining the level of the return object for the purpose of defining the level of explicitly aliased parameters; this follows from the fact that explicitly aliased parameters are always defined to have the level of the return object by 3.10.2(13.3/3), but it surely is convoluted. Since we're talking about when we're not in a return statement, we can't have any access to the return object.) > As far as the access > discriminant check, the interesting case is when the aliased parameter > is of a class-wide type, and we don't know until run-time whether > there is an access discriminant. > > So the case of interest is: > function F (L : aliased T'Class) return Natural is > begin > P := new T'Class(L); > return 2; > end F; > > I would say this should fail if L has any access discriminants, > independent of the actual parameter's accessibility. > We aren't passing an accessibility level along with "aliased" > parameters, so I don't see how we could know the "true" > accessibility level of the actual parameter anyway. The point of > aliased parameters is that a reference to some part of the parameter > can be returned from the function. In other contexts, they behave > just like "regular" parameters (except that they are aliased, of > course). OK, but how in heaven's name do you propose to accomplish this? This is a *dynamic* check, so the static accessibility is irrelevant. I suppose you could try to craft a legality rule specifically for this case, but that is going to make a lot legitimate code illegal. The alternative is to say that the dynamic accessibility of an explicitly aliased parameter depends on where it is used -- an idea that I'm strongly opposed to (I have no idea how to code generate that -- remember that the uses could be deeply nested in very complex expressions -- how would you do it??). **************************************************************** From: Tucker Taft Sent: Monday, February 14, 2011 1:55 PM I think this is the e-mail related to AI-234 that you indicated was still awaiting a response. So here is my response. ... > Why do you say that? Maybe it *should* have failed, but that doesn't > appear to be the case. > > For the static check, 3.10.2(19.3/3) says in part: > > ...for statically comparing with the level of other entities, the > level of the return object of F is considered to be the same as that > of the master that elaborated the function body of F. I think you are cheating a bit here, since the first part of this sentence specifically addresses what happens when you compare the accessibility level of a return object with an aliased param. Perhaps this paragraph should go on to say that when statically comparing the level of an aliased parameter with anything but the return object of F, the aliased parameter is treated like a local variable. That might obviate any separate rule for the accessibility level of an aliased parameter. > > The master that elaborated A_T and the master that elaborated F are > the same, so I can't see any reason for the static check to have > failed in this example. > > Are you saying this wording is not what we intended? That's surely > possible; I was trying to figure out the consequences assuming that it > was correct, but perhaps that was a waste of time. > > (I note this wording seems to have lost the fact that it is defining > the level of the return object for the purpose of defining the level > of explicitly aliased parameters; this follows from the fact that > explicitly aliased parameters are always defined to have the level of > the return object by 3.10.2(13.3/3), but it surely is convoluted. > Since we're talking about when we're not in a return statement, we > can't have any access to the return > object.) OK, I see your logic, and that convinces me that we should either make the change I suggested above, or change 13.3/3 to say something like: Within a return statement that applies to a function body, the accessibility level of an explicitly aliased (see 6.1) formal parameter of the function is determined by the point of call; it is the same level that the return object ultimately will have. Outside of a return statement that applies to the function body, the formal parameter has the same accessibility level as that of any other formal parameter[Redundant:, namely that of the master representing the invocation of the function body]. I think I somewhat prefer making the change to the rules associated with statically comparing aliased parameters, and eliminate the separate standalone rule in 13.3/3 for the accessibility level of an aliased parameter. Then they would follow the normal rule for formal parameters, namely they are treated like local variables, except when being statically compared against the level of the return object. >> As far as the access >> discriminant check, the interesting case is when the aliased >> parameter is of a class-wide type, and we don't know until run-time >> whether there is an access discriminant. >> >> So the case of interest is: >> function F (L : aliased T'Class) return Natural is >> begin >> P := new T'Class(L); >> return 2; >> end F; >> >> I would say this should fail if L has any access discriminants, >> independent of the actual parameter's accessibility. >> We aren't passing an accessibility level along with "aliased" >> parameters, so I don't see how we could know the "true" >> accessibility level of the actual parameter anyway. The point of >> aliased parameters is that a reference to some part of the parameter >> can be returned from the function. In other contexts, they behave >> just like "regular" parameters (except that they are aliased, of >> course). > > OK, but how in heaven's name do you propose to accomplish this? This > is a > *dynamic* check, so the static accessibility is irrelevant. I suppose > you could try to craft a legality rule specifically for this case, but > that is going to make a lot legitimate code illegal. The alternative > is to say that the dynamic accessibility of an explicitly aliased > parameter depends on where it is used -- an idea that I'm strongly > opposed to (I have no idea how to code generate that -- remember that > the uses could be deeply nested in very complex expressions -- how would you do it??). I believe 4.8(10.1) already addresses this case, and the fact that L is an aliased parameter should make no difference. Now if the allocator were inside the return statement for F, then the fact that L is aliased could make a difference, in that the objects designated by its access discriminants must live at least as long as the return object, but that still isn't very long. **************************************************************** From: Randy Brukardt Sent: Monday, February 14, 2011 7:52 PM > I think you are cheating a bit here, since the first part of this > sentence specifically addresses what happens when you compare the > accessibility level of a return object with an aliased param. Perhaps > this paragraph should go on to say that when statically comparing the > level of an aliased parameter with anything but the return object of > F, the aliased parameter is treated like a local variable. > That might obviate any separate rule for the accessibility level of an > aliased parameter. I'm not cheating per-se; the original intent of the static check was to represent the "half-level" model for return objects and aliased parameters. This was an attempt to word that model. Probably the problem here is that the "half-level" model really doesn't have any useful effect for parameters outside of return statements. About the only case where it might be meaningful would be an assignment from one aliased parameter to an anonymous component of another - no, even that doesn't work. So probably we should just replace 3.10.2(19.2/3) with something like: Inside a return statement that applies to a function F, when determining whether the accessibility level of an explicitly aliased parameter of F is statically deeper than the level of the return object of F, the level of the return object is considered to be the same as that of the level of the explicitly aliased parameter; for statically comparing with the level of other entities, the level of an explicitly aliased parameters of F is considered to be the same as that of a local object of F. Aside about AI05-0235-1: It appears that the old wording for parameters was intended to have a double meaning -- it seems to mean something different for static and dynamic accessibility. Since we rewrote the paragraph to make sense for dynamic accessibility, it no longer works for static accessibility (the levels aren't statically nested, so we can't apply 3.10.2(18)). I wonder if we need a more general bullet for parameters: * Unless otherwise specified, the accessibility level of a formal parameter of a callable entity is considered to be the same as that of a local object of F. Perhaps we should put this entire discussion into AI05-0235-1 -- except that Steve wants to use his handy-dandy "ultimate accessibility levels" in 3.10.2(13.3/3). End aside. ... > OK, I see your logic, and that convinces me that we should either make > the change I suggested above, or change 13.3/3 to say something like: > > Within a return statement that applies to a function body, the > accessibility level of an explicitly aliased (see 6.1) formal > parameter of the function is determined by the point of call; > it is the same level that the return object ultimately will have. > Outside of a return statement that applies to the function body, > the formal parameter has the same accessibility level as that > of any other formal parameter[Redundant:, namely that of the master > representing the invocation of the function body]. I don't think we want to mess with the dynamic accessibility rules. I strongly object to having a context-dependent dynamic accessiblity check: I don't think there are any cases currently -- the value is always determined by the entity being checked. It sounds like a pain to implement context-specific checks (given these can be nested in many levels of calls and allocators). ... > >> As far as the access > >> discriminant check, the interesting case is when the aliased > >> parameter is of a class-wide type, and we don't know until run-time > >> whether there is an access discriminant. > >> > >> So the case of interest is: > >> function F (L : aliased T'Class) return Natural is > >> begin > >> P := new T'Class(L); > >> return 2; > >> end F; > >> > >> I would say this should fail if L has any access discriminants, > >> independent of the actual parameter's accessibility. > >> We aren't passing an accessibility level along with "aliased" > >> parameters, so I don't see how we could know the "true" > >> accessibility level of the actual parameter anyway. The point of > >> aliased parameters is that a reference to some part of the > >> parameter can be returned from the function. In other contexts, > >> they behave just like "regular" parameters (except that they are > >> aliased, of course). > > > > OK, but how in heaven's name do you propose to accomplish this? This > > is a > > *dynamic* check, so the static accessibility is irrelevant. I > > suppose you could try to craft a legality rule specifically for this > > case, but that is going to make a lot legitimate code illegal. The > > alternative is to say that the dynamic accessibility of an > > explicitly aliased parameter depends on where it is used -- an idea > > that I'm strongly opposed to (I have no idea how to code generate > > that -- remember that the uses could be deeply nested in very > > complex expressions > -- how would you do it??). > > I believe 4.8(10.1) already addresses this case, and the fact that L > is an aliased parameter should make no difference. > Now if the allocator were inside the return statement for F, then the > fact that L is aliased could make a difference, in that the objects > designated by its access discriminants must live at least as long as > the return object, but that still isn't very long. I think Steve is trying to address this case, so my question is OBE. So I recommend leaving 3.10.2(13.3/3) [modulo changing it to use Steve's "ultimate accessibility level" rather than "the level that the return object will ultimately have", which is the same thing, but the former is worded more formally]. Note that the dynamic check is definitely needed in these cases (the AI05-0234-1 cases), so removing that definition is not going to work. Probably this case gets left in AI05-0234-1, and we'll let Steve get it exactly right. The static case probably should get dumped into AI05-0235-1, since it is at least as closely related to that. Thoughts?? **************************************************************** From: Tucker Taft Sent: Monday, February 14, 2011 8:15 PM > So probably we should just replace 3.10.2(19.2/3) with something like: > > Inside a return statement that applies to a function F, when > determining whether the accessibility level of an explicitly aliased > parameter of F is statically deeper than the level of the return > object of F, the level of the return object is considered to be the > same as that of the level of the explicitly aliased parameter; for > statically comparing with the level of other entities, the level of an > explicitly aliased parameters of F is considered to be the same as that of a local object of F. That sounds about right. > Aside about AI05-0235-1: It appears that the old wording for > parameters was intended to have a double meaning -- it seems to mean > something different for static and dynamic accessibility. Since we > rewrote the paragraph to make sense for dynamic accessibility, it no > longer works for static accessibility (the levels aren't statically > nested, so we can't apply 3.10.2(18)). I wonder if we need a more general bullet for parameters: > > * Unless otherwise specified, the accessibility level of a formal > parameter of a callable entity is considered to be the same as that of > a local object of F. I'm not sure why we need the "unless otherwise specified" any more. > Perhaps we should put this entire discussion into AI05-0235-1 -- > except that Steve wants to use his handy-dandy "ultimate accessibility > levels" in 3.10.2(13.3/3). > End aside. > > ... >> OK, I see your logic, and that convinces me that we should either >> make the change I suggested above, or change 13.3/3 to say something >> like: >> >> Within a return statement that applies to a function body, the >> accessibility level of an explicitly aliased (see 6.1) formal >> parameter of the function is determined by the point of call; >> it is the same level that the return object ultimately will have. >> Outside of a return statement that applies to the function body, >> the formal parameter has the same accessibility level as that >> of any other formal parameter[Redundant:, namely that of the master >> representing the invocation of the function body]. > > I don't think we want to mess with the dynamic accessibility rules. I > strongly object to having a context-dependent dynamic accessiblity > check: I don't think there are any cases currently -- the value is > always determined by the entity being checked. It sounds like a pain > to implement context-specific checks (given these can be nested in > many levels of calls and allocators). I *think* we are agreeing here, namely we should get rid of 13.3/3, and make the change you suggested above to 19.2/3. > I think Steve is trying to address this case, so my question is OBE. > So I recommend leaving 3.10.2(13.3/3) [modulo changing it to use > Steve's "ultimate accessibility level" rather than "the level that the > return object will ultimately have", which is the same thing, but the > former is worded more formally]. Why do we need paragraph 13.3/3 any more? > Note that the dynamic check is definitely needed in these cases (the > AI05-0234-1 cases), so removing that definition is not going to work. > > Probably this case gets left in AI05-0234-1, and we'll let Steve get > it exactly right. > > The static case probably should get dumped into AI05-0235-1, since it > is at least as closely related to that. > > Thoughts?? I agree this doesn't really have much to do with AI-234. But based on the above, I think we don't actually need AI-235 any more. The only change I think we need is to 19.2/3, so really we are re-opening AI-142, and perhaps that is what AI-235 really is -- fixes to AI-142. **************************************************************** From: Randy Brukardt Sent: Monday, February 14, 2011 8:57 PM > > So probably we should just replace 3.10.2(19.2/3) with something like: > > > > Inside a return statement that applies to a function F, when > > determining whether the accessibility level of an > explicitly aliased > > parameter of F is statically deeper than the level of the return > > object of F, the level of the return object is considered to be the > > same as that of the level of the explicitly aliased parameter; for > > statically comparing with the level of other entities, the > level of an > > explicitly aliased parameters of F is considered to be the > same as that of a local object of F. > > That sounds about right. OK. But then you go way off the rails below. > > Aside about AI05-0235-1: It appears that the old wording for > > parameters was intended to have a double meaning -- it > seems to mean > > something different for static and dynamic accessibility. Since we > > rewrote the paragraph to make sense for dynamic > accessibility, it no > > longer works for static accessibility (the levels aren't statically > > nested, so we can't apply 3.10.2(18)). I wonder if we need > a more general bullet for parameters: > > > > * Unless otherwise specified, the accessibility level of a formal > > parameter of a callable entity is considered to be the same > as that of > > a local object of F. > > I'm not sure why we need the "unless otherwise specified" any more. Because we still have the exception about "inside a return statement" in 3.10.2(19.2/3). We don't want conflicting rules for them. I also will repeat that this is in *addition* to the rewording proposed in 3.10.2(7/2). Maybe we can come up with a better rewording for the existing paragraph, so we don't need this extra bullet, but this one is purely intended to be a static check. We *always* need a dynamic level defined as well. ... > > I don't think we want to mess with the dynamic accessibility rules. > > I strongly object to having a context-dependent dynamic > > accessibility > > check: I don't think there are any cases currently -- the value is > > always determined by the entity being checked. It sounds like a pain > > to implement context-specific checks (given these can be nested in > > many levels of calls and allocators). > > I *think* we are agreeing here, namely we should get rid of 13.3/3, > and make the change you suggested above to 19.2/3. No, because both the static and dynamic checks are applied to all entities. (Generally, the compiler can prove that one or the other aren't needed.) In particular, none of the rules about the dynamic check say anything about not applying them if the static check succeeds. So, the exception in 3.10.2(19.2/3) eliminates the static check within the return statement. But the dynamic check would then fail if we didn't have a special definition for the dynamic level for explicitly aliased parameters (because they would be treated as local objects). So we need the rules for the dynamic level for explicitly aliased parameters (since these are shallower than the "normal" parameter levels, it shouldn't require any additional checks or overhead, other than for AI05-0234-1 which has that effect for everything). > > I think Steve is trying to address this case, so my question is OBE. > > So I recommend leaving 3.10.2(13.3/3) [modulo changing it to use > > Steve's "ultimate accessibility level" rather than "the level that > > the return object will ultimately have", which is the same thing, > > but the former is worded more formally]. > > Why do we need paragraph 13.3/3 any more? See above. > > Note that the dynamic check is definitely needed in these cases (the > > AI05-0234-1 cases), so removing that definition is not going to work. > > > > Probably this case gets left in AI05-0234-1, and we'll let Steve get > > it exactly right. > > > > The static case probably should get dumped into AI05-0235-1, since > > it is at least as closely related to that. > > > > Thoughts?? > > I agree this doesn't really have much to do with AI-234. > But based on the above, I think we don't actually need AI-235 any > more. The only change I think we need is to 19.2/3, so really we are > re-opening AI-142, and perhaps that is what > AI-235 really is -- fixes to AI-142. Now I'm very confused. The change in AI05-0235-1 was because the wording in 3.10.2(7/2) is vague and conflicts with both 3.10.2(13.3/3 and 19.2/3). I suggested adding a new bullet to the static rules after removing the vagueness from 3.10.2(7/2) -- it appears to me that the reason it is vague was so that it could be two completely different meanings for dynamic and static accessibility levels -- but that is nasty and I much prefer having these things make sense. Somehow you've turned that into abandoning AI05-0142-4 (because the entire point is in the rules 3.10.2(13.3/3) and 3.10.2(19.2/3)) and leaving the impossibility to understand in 3.10.2(7.2). I've lost you here. I think it is fine to repurpose AI05-0235-1 to fix this problem, but not to ignore the problems or abandon the efforts on aliased parameters. **************************************************************** From: Tucker Taft Sent: Monday, February 14, 2011 9:22 PM I think we will need to carry this discussion over to the ARG meeting. In my experience, these accessibility questions need to be worked on a white-board, perhaps in a group, and maybe with a beer or two handy... In any case, I do see most of your points, I just haven't got the stamina to work through this further at this point. I suggest you write up what you have in mind. It may be fine. I was perhaps vainly hoping that we could simplify this a bit. **************************************************************** From: Randy Brukardt Sent: Monday, February 14, 2011 9:32 PM OK, I admit I'm running out of stamina on this one, too. I think we might need a keg of beer, though. ;-) [I'd suggest Rochfort 10. :-)] I'm thinking that maybe there is a way to reword 3.10.2(7/2) that doesn't include "invocation" (which is what messes up the static accessibility level). I think my clunky wording didn't have that problem, but your improved wording messed that up (even though I much prefer it to mine). If that works, then at least we would only need to change two paragraphs. **************************************************************** From: Steve Baird Sent: Thursday, March 3, 2011 4:58 PM > Related to AI05-0235-1 (but would cause a new AI): Is there a problem > with accessibility checks (especially dynamic ones) for explicitly > aliased parameters of task entries?? Does this cause "comparability" problems?? > I think there is no problem here. Marking a parameter of a non-function (e.g., of an entry) as aliased just means, from the callee's perspective, that it can be treated in much the same way as an aliased local. The !summary section of AI05-0235 says Explicitly aliased parameters have special accessibility only within the return statement of a function; otherwise, they have the same accessibility as "normal" parameters. **************************************************************** From: Randy Brukardt Sent: Friday, March 4, 2011 10:28 PM To expand on this a bit: tagged types already can be used as the prefix of 'Access. So if there was a problem, it would already have appeared with such tagged parameters of an entry. Explicitly aliased parameters add nothing new vis-a-vis accessibility. ****************************************************************