!standard 3.10.2(15) 07-05-25 AI05-0014-1/03 !class binding interpretation 06-05-12 !status Amendment 201Z 08-11-26 !status WG9 Approved 07-06-29 !status ARG Approved 7-0-0 06-06-11 !status work item 06-05-12 !status received 06-04-24 !priority High !difficulty Easy !qualifier Omission !subject Accessibility of designated objects !summary (See recommendation.) !question 3.10.2(15) says: The accessibility level of a view of an object or subprogram denoted by a dereference of an access value is the same as that of the access type. But what is the accessibility of the designated object or subprogram if it is needed, but no dereference is present? For example, using Ada 2005: C : access Thing; .... C := Func_Returns_Ptr; .... return new Rec (D => C, ...); We will need to know the accessibility level of the discriminant, and this depends on that of the object designated by C (3.10.2(12.2)). But 3.10.2(15) does not apply, as there is no dereference in this code. Similarly, in Ada 95: type Acc is access all Thing; C : Acc := Some_Obj'Access; procedure P (Arg : access Thing); P (C); We need to know what the accessibility level of Arg is inside of P, and that level is defined to be that of the "view of the designated object" (3.10.2(13/2)). Again, there is no dereference in this code. !recommendation 3.10.2(15) needs to apply to all objects designated by an access value. Note that this Binding Interpretation applies to Ada 95 as well as Ada 2005. !wording In 3.10.2(15), replace "denoted by a dereference of an access value" by "designated by an access value". !discussion It would be bizarre if the presence or absence of ".all" (implicitly or explicitly) changed the accessibility level of a designated object. Moreover, we do not want to have to carry dynamic accessibility levels with access objects. Thus, we reword 3.10.2(15) to have this effect. This means that the object designated by C in the two examples above always has the accessibility level of C; it does not have the level of the object returned by the function or of Some_Obj. !corrigendum 3.10.2(15) @drepl @xbullet @dby @xbullet !ACATS test An ACATS C-Test should be created to test these cases to ensure that the levels are correct. !appendix From: Gary Dismukes Date: Monday, April 24, 2006 3:54 PM The bulleted rule in 3.10.2(12.2/2) looks wrong to me. This is part of the rules for defining the level of access discriminants in allocators and return statements (3.10.2(12/2), and says: * If the value of the access discriminant is determined by a component_ association in an aggregate, the accessibility level of the object or subprogram designated by the associated value (or library level if the value is null); But the level of the entity designated by the access value isn't known at compile time in general. It might be an object designated by a local access object A where the object could be at the local level or higher (or the value of A might be null). However this would seem to imply the need to associate a level with allocated objects, and that can't be what's intended. Shouldn't this rule be talking about the accessibility level of the type of the access value, rot that of the designated entity? Am I missing something? (Looks like this issue arises for paragraph 12.1/2 as well.) **************************************************************** From: Tucker Taft Date: Monday, April 24, 2006 4:12 PM I tend to resist saying anything about accessibility levels without spending a few hours refreshing myself on all the rules, but one thing I do know is that accessibility levels are *run time* values. We talk about one being "statically deeper" than another, but in general, the levels are defined dynamically. Be that as it may, you may very well be right, but I haven't got the time at this moment to enter the "Zen of accessibility levels" needed to really answer your question... **************************************************************** From: Tucker Taft Date: Monday, April 24, 2006 4:27 PM Well, I couldn't resist doing a bit more investigation. The key thing is that this rule only applies in a very narrow context. When you later refer to the allocated object in some other context, the level of the access discriminants are determined by the level of the object, so there is no need to store this information. The level given by this rule is needed to properly enforce the following rule (from 4.8(5.2)): If the designated subtype of the type of the allocator has one or more unconstrained access discriminants, then the accessibility level of the anonymous access type of each access discriminant, as determined by the subtype_indication or qualified_expression of the allocator, shall not be statically deeper than that of the type of the allocator (see 3.10.2). There is a similar rule associated with return statements. The problem we are trying to solve with 3.10.2(12.2/2) is that when the allocator is first performed, we need to decide whether the value given for the access discriminant is "safe" to be used with the implied storage pool. By safe we mean that when we later use it, and don't have any context, and hence assume it has the same level as that of the enclosing allocated object, we will we get a "safe" answer. The key requirement is that the designated object must outlive the allocated object. It is admittedly a round-about way of accomplishing this key requirement, and perhaps someone else could come up with a way of formulating these rules so they accomplish this more simply. But I struggled mightily with them and this was the best I could do. **************************************************************** From: Edmond Schonberg Date: Monday, April 24, 2006 4:38 PM But we see no way to implement that check without carrying accessibility levels where they did not previously exist (at run time) C : access Thing; .... C := Func_Returns_Ptr; return new Rec (D => C....); If the legality rule depends on the accessibility level of the type of C, everything is clear. If it depends on the value returned by the function call, this is a new notion altogether. **************************************************************** From: Randy Brukardt Date: Monday, April 24, 2006 4:58 PM I don't see a problem with this example. The rule (3.10.2(12.2/2)) refers the accessibility of the object. The object in this case is C.all. The accessibility of C.all is governed by 3.10.2(15), which says it is the same as the type (in this case "access Thing"). The type of C has the accessibility of whether C is declared. The assignment to C might make a dynamic accessibility check, but once that's done, there is no need to carry the value further. What have I missed?? **************************************************************** From: Edmond Schonberg Date: Monday, April 24, 2006 5:23 PM Nothing. I guess I missed the fact that 3.10.2 (15) applies here, when there is no dereference in sight. I will have to make that mental substitution every time I see "denoted by" in this section. Thanks for the clarification! **************************************************************** From: Gary Dismukes Date: Monday, April 24, 2006 5:31 PM > I don't see a problem with this example. The rule (3.10.2(12.2/2)) refers > the accessibility of the object. The object in this case is C.all. The > accessibility of C.all is governed by 3.10.2(15), which says it is the same > as the type (in this case "access Thing"). The type of C has the > accessibility of whether C is declared. Well, rule 3.10.2(15) defines the level of an object "denoted by a dereference of an access value", but that's talking about something like C.all (or an implicit dereference of C) occurring in the program. Just mentioning C by itself doesn't seem to qualify as a dereference. But something very like that rule would seem to be what's needed. It looks like if it just said "denoted by an access value" rather than saying a dereference that might do the trick. > The assignment to C might make a dynamic accessibility check, but once > that's done, there is no need to carry the value further. > > What have I missed?? I couldn't find a rule that related to access values themselves. At one point I noticed 3.10.2(15) but took it at its word that it only applied to actual dereferences. Anyway, I think we agree on what's intended for 3.10.2(12.2/2), and fixing it is probably not difficult (for example by a tweak or addition to 3.10.2(15)). **************************************************************** From: Randy Brukardt Date: Monday, April 24, 2006 5:39 PM Humm, there is a bit of a leap there; but since the alternative way leads to madness, applying Dewar's rule means it must apply. Specifically, if the derference rule did not apply, it would be necessary to have a runtime indication of accessibility level with all designated objects. In order to check that level, you would need to dereference the access value. So, we'd be saying that a dereference isn't a dereference unless it appears in the program text. That seems like hair-splitting (not to mention the difficulty of doing runtime levels correctly). It certainly would be nice to have clearer wording here, though. **************************************************************** From: Tucker Taft Date: Monday, April 24, 2006 7:17 PM This wording is very similar to the largely unchanged Ada 95 wording that is used in 3.10.2(13/2): The accessibility level of the anonymous access type of an access parameter specifying an access-to-object type is the same as that of the view designated by the actual. It would be even more similar if we changed "the accessibility level of the object or subprogram designated by the associated value" to "the accessibility level of the view of an object or subprogram designated by the associated value." But it barely seems necessary... **************************************************************** From: Edmond Schonberg Date: Monday, April 24, 2006 7:47 PM > This wording is very similar to the largely unchanged Ada 95 > wording that is used in 3.10.2(13/2): > > The accessibility level of the anonymous access type of > an access parameter specifying an access-to-object type > is the same as that of the view designated by the actual. Now I'm really lost. This is the one case that requires a runtime check, and we were discussing a case that doesn't. There may be some parallel in the phrasing, but I truly fail to see how it applies to example we were struggling with. **************************************************************** From: Randy Brukardt Date: Monday, April 24, 2006 7:54 PM > This wording is very similar to the largely unchanged Ada 95 > wording that is used in 3.10.2(13/2): ... Right. And I think your point is that the issue exists in Ada 95 (even though it takes more work): type Acc is access all Thing; C : Acc := Some_Obj'Access; procedure P (Arg : access Thing); P (C); -- C has the accessibility level of Acc inside of P, not Some_Obj. But in any case, I think everyone agrees that there is no problem with 3.10.2(12.2/2) or 3.10.2(13/2). The problem is that 3.10.2(15) [which is also unchanged] is assumed to apply to this case; but there is no "dereference" in the sense of 4.1 in either of these examples. Thus it can be argued that 3.10.2(15) does not apply; and there is no other rule specifying the accessibility of "the view designated" by an access type. That means you have to revert to the accessibility of the actual designated object, and then you have to carry that along with the access value. The only interesting question is whether "dereference" means "dereference" in the sense of 4.1, in which case there is a problem when there is no such dereference. I say it cannot, because any other result is madness -- but that's usually the case where a wording change ought to be considered. And this wording change is needed for Ada 95 as well; the bug (if it is one) goes way back. **************************************************************** From: Randy Brukardt Date: Monday, April 24, 2006 8:45 PM > Now I'm really lost. Accessibility tends to have that effect on people. :-) > This is the one case that requires a runtime > check, and we were discussing a case that doesn't. There may be some > parallel in the phrasing, but I truly fail to see how it applies to > example we were struggling with. I *think* Tucker was referring to how the accessibility of the actual is determined (not the accessibility of the parameter itself). See the example in my previous message. But I fail to see what difference the phrasing makes - 3.10.2(15) either does or doesn't apply in both cases, and without that you have to look at the object itself. **************************************************************** From: Tucker Taft Date: Monday, April 24, 2006 8:51 PM > Now I'm really lost. This is the one case that requires a runtime check, > and we were discussing a case that doesn't. There may be some parallel > in the phrasing, but I truly fail to see how it applies to example we > were struggling with. I believe it is exactly the same. There is no run-time check when you are *passing* an access parameter, only when you try to convert it to some other access type. But the key thing is that if you take the same example you gave originally: C : access Thing; .... C := Func_Returns_Ptr; return new Rec (D => C....); And replace the "return" statement with a call: Proc_With_Acc_Param(C); the accessibility level passed here is independent of what you assign into C. It is based strictly on the accessibility level determined at the point where C is declared, which in this case is that of the declaration (presuming C is a local variable). Nevertheless, we refer to this as the accessibility level of the view designated by C, in case C is itself also an access parameter. This same thing would apply for the return statement, if C is itself an access parameter rather than a local variable. The accessibility level to be checked would come from the accessibility of the "view" designated by C, and that would be a run-time value. But in *your* example, the accessibility level associated with "C" is essentially static, since local variables of an anon access type have a level that comes from the level of the declaration. I agree that the wording is not ideal, but in many places we talk about accessibility levels and they always depend on the "view" in the current context, not on the "true" lifetime of the underlying object. If you find it handy to think of it in terms of C.all that might be helpful, but you would need to do that for the preexisting wording in 3.10.2(13) I would claim. **************************************************************** From: Randy Brukardt Date: Monday, April 24, 2006 9:08 PM ... > And replace the "return" statement with a call: > > Proc_With_Acc_Param(C); > > the accessibility level passed here is independent > of what you assign into C. It is based strictly > on the accessibility level determined at the point where > C is declared, which in this case is that of the > declaration (presuming C is a local variable). I agree with the *result* here, but you need to show me the exact wording that makes this true. So far as I can tell, the only rule that discusses the accessibility of the view of an object designated by an access value is 3.10.2(15) -- and that rule arguably does not apply in this case. So far as I can tell, this is a bug in Ada 95 as well as in Ada 2005. You're certainly right that nothing has changed here: but the words, taken literally, seem to give a nonsense result. Everyone has agreed its a nonsense result, the only question is whether there is some wording that someone has missed that eliminates the nonsense result. If you disagree, please show the paragraphs and logic that makes this true. The accessibility rules are inscrutable enough that you really do need to give a complete exegesis. **************************************************************** From: Tucker Taft Date: Monday, April 24, 2006 9:02 PM >> This wording is very similar to the largely unchanged Ada 95 >> wording that is used in 3.10.2(13/2): > ... > > Right. And I think your point is that the issue exists in Ada 95 (even > though it takes more work): > > type Acc is access all Thing; > C : Acc := Some_Obj'Access; > procedure P (Arg : access Thing); > > P (C); -- C has the accessibility level of Acc inside of P, not > Some_Obj. Correct. > But in any case, I think everyone agrees that there is no problem with > 3.10.2(12.2/2) or 3.10.2(13/2). The problem is that 3.10.2(15) [which is > also unchanged] is assumed to apply to this case; but there is no > "dereference" in the sense of 4.1 in either of these examples. Thus it can > be argued that 3.10.2(15) does not apply; and there is no other rule > specifying the accessibility of "the view designated" by an access type. I see your point. 3.10.2(15) should probably have simply said "designated by an access value" rather than "denoted by a dereference of an access value." > The only interesting question is whether "dereference" means "dereference" > in the sense of 4.1, in which case there is a problem when there is no such > dereference. I say it cannot, because any other result is madness -- but > that's usually the case where a wording change ought to be considered. And > this wording change is needed for Ada 95 as well; the bug (if it is one) > goes way back. Well I guess that was my main point. The new wording in 3.10.2(12.2) is essentially equivalent to the old wording in 3.10.2(13), and both suffer from the same problem that they say "designated by" when 3.10.2(15) says "denoted by a dereference of." But I hope we agree that "denoted by a dereference of" and "designated by" are very, very close in meaning. As it says in 4.1(13): ... The dereference denotes the object or subprogram designated by the value of the name. **************************************************************** From: Randy Brukardt Date: Monday, April 24, 2006 9:15 PM ... > I see your point. 3.10.2(15) should probably have simply said > "designated by an access value" rather than "denoted by a dereference > of an access value." OK, that's what Gary suggested. (And you can ignore my most recent message, which crossed in the mail with this one.) > > The only interesting question is whether "dereference" means "dereference" > > in the sense of 4.1, in which case there is a problem when there is no such > > dereference. I say it cannot, because any other result is madness -- but > > that's usually the case where a wording change ought to be considered. And > > this wording change is needed for Ada 95 as well; the bug (if it is one) > > goes way back. > > Well I guess that was my main point. The new wording in > 3.10.2(12.2) is essentially equivalent to the old wording > in 3.10.2(13), and both suffer from the same problem that > they say "designated by" when 3.10.2(15) says "denoted > by a dereference of." But I hope we agree that "denoted > by a dereference of" and "designated by" are very, very > close in meaning. As it says in 4.1(13): > > ... The dereference denotes the object or subprogram > designated by the value of the name. I don't think there is any argument. Gary just didn't like my exegesis using 3.10.2(15), because there was no "dereference" as defined in the language. And he's right, formally. Practically, I doubt there is much rush to fix this, so long as everyone agrees. **************************************************************** From: Pascal Leroy Date: Tuesday, April 25, 2006 3:45 AM I am in favor of fixing bugs, and this is obviously a bug. The fix should be along the lines suggested by Tuck: 3.10.2(15) should probably have simply said "designated by an access value" rather than "denoted by a dereference of an access value." It is true that the bug has been with us for a long time, but if it confused Ed and Gary it could confuse other people. The accessibility rules are so intricate now that any inaccuracy can lead to serious misunderstandings. ****************************************************************