Version 1.5 of ai05s/ai05-0014-1.txt

Unformatted version of ai05s/ai05-0014-1.txt version 1.5
Other versions for file ai05s/ai05-0014-1.txt

!standard 3.10.2(15)          07-05-25 AI05-0014-1/03
!class binding interpretation 06-05-12
!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)
Replace the paragraph:
by:
!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.

****************************************************************


Questions? Ask the ACAA Technical Agent