Version 1.1 of acs/ac-00053.txt

Unformatted version of acs/ac-00053.txt version 1.1
Other versions for file acs/ac-00053.txt

!standard 13.10(03)          03-06-23 AC95-00053/01
!class amendment 03-06-23
!status received no action 03-06-23
!subject How far does Unchecked_Access propagate?
!summary
!appendix

!topic How far does Unchecked_Access propagate?
!reference RM95 13.10(3)
!from Adam Beneschan 05-20-03
!discussion

I have a question about just what checks are suppressed when
'Unchecked_Access is used.  The RM says about this attribute:

  All rules and semantics that apply to X'Access (see 3.10.2) apply
  also to X'Unchecked_Access, except that, for the purpose of
  accessibility rules and checks, it is as if X were declared
  immediately within a library package.

Which checks does this rule apply to?  One possible interpretation is
that it applies to the checks (both at compile- and at run-time) that
would take place for the construct in which the 'Unchecked_Access
attribute appears.  Another possible interpretation is that it creates
an "unchecked" access value for which no accessibility checks are
performed anywhere this access value is used; i.e. the "unchecked"
attribute lives with the access value and is propagated with it.  GNAT
appears to follow the second interpretation, at least in the example
below (unless this is just a GNAT bug):

    package pak1 is
       type Object is tagged null record;
       type Object_Class is access all Object'Class;
       procedure P1 (O : access Object);
       Robj : Object_Class;
    end pak1;

    package body pak1 is

       procedure P1 (O : access Object) is
       begin
          Robj := Object_Class(O);
       end p1;

    end pak1;

    with Pak1;
    with Text_IO;
    procedure Test87 is

       procedure P2 (H3 : in Pak1.Object_Class) is
       begin
          Pak1.P1 (H3);
       end P2;

       X1: aliased Pak1.Object;

    begin
       P2 (X1'Unchecked_Access);
    exception
       when Program_Error =>
          Text_IO.Put_Line ("Program_Error");
    end Test87;

Using the first interpretation, the program would print
"Program_Error", because although it would be legal to pass
X1'Unchecked_Access to P2 (using 'Access would be illegal here), the
access parameter O (the "view designated by the actual", in terms of
3.10.2(13)) would still have an accessibility level of "inside
Test87", and the type conversion inside P1 would thus be illegal
(4.6(48)).  Using the second interpretation, 'Unchecked_Access would
create a "special" access value that appears to designate an object
declared immediately within a library package, and this access value
would eventually be passed to P1, making the accessibility level of O
library level, making the type conversion legal.

Which interpretation is correct, and what's the correct behavior of
the above program?

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

From: Gary Dismukes
Sent: Tuesday, May 20, 2003  6:52 PM

The object should be treated as library-level, meaning that its
accessibility level should continue to reflect that when passed to
other procedures.  That seems fairly clear from the RM wording.
So any accessibility checks should treat the access value as
designating a library-level object and no exception should be
raised in your example.

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

From: Adam Beneschan
Sent: Wednesday, May 21, 2003  11:20 AM

> I have a question about just what checks are suppressed when
> 'Unchecked_Access is used.  The RM says about this attribute: . . .

After sleeping on this, I've realized that the example I provided is
flawed, plus I might have misinterpreted something in 3.10.2.  I'll
withdraw my question for the time being, but I think there still might
be an issue in there somewhere, so I'll study this further.

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

From: Adam Beneschan
Sent: Wednesday, May 21, 2003  12:06 PM

OK, it appears that I blew it.  However, maybe I can find a way to pin
the blame on the RM.

I wrote:

> I have a question about just what checks are suppressed when
> 'Unchecked_Access is used.  The RM says about this attribute:
>
>   All rules and semantics that apply to X'Access (see 3.10.2) apply
>   also to X'Unchecked_Access, except that, for the purpose of
>   accessibility rules and checks, it is as if X were declared
>   immediately within a library package.
>
> Which checks does this rule apply to?  One possible interpretation is
> that it applies to the checks (both at compile- and at run-time) that
> would take place for the construct in which the 'Unchecked_Access
> attribute appears.  Another possible interpretation is that it creates
> an "unchecked" access value for which no accessibility checks are
> performed anywhere this access value is used; i.e. the "unchecked"
> attribute lives with the access value and is propagated with it.  GNAT
> appears to follow the second interpretation, at least in the example
> below (unless this is just a GNAT bug):
>
>     package pak1 is
>        type Object is tagged null record;
>        type Object_Class is access all Object'Class;
>        procedure P1 (O : access Object);
>        Robj : Object_Class;
>     end pak1;
>
>     package body pak1 is
>
>        procedure P1 (O : access Object) is
>        begin
>           Robj := Object_Class(O);
>        end p1;
>
>     end pak1;
>
>     with Pak1;
>     with Text_IO;
>     procedure Test87 is
>
>        procedure P2 (H3 : in Pak1.Object_Class) is
>        begin
>           Pak1.P1 (H3);
>        end P2;
>
>        X1: aliased Pak1.Object;
>
>     begin
>        P2 (X1'Unchecked_Access);
>     exception
>        when Program_Error =>
>           Text_IO.Put_Line ("Program_Error");
>     end Test87;
>
> Using the first interpretation, the program would print
> "Program_Error", because although it would be legal to pass
> X1'Unchecked_Access to P2 (using 'Access would be illegal here), the
> access parameter O (the "view designated by the actual", in terms of
> 3.10.2(13))

Here was my mistake.  The problem was that I interpreted the phrase
"[the accessibility level] of the view designated by the actual" to
mean "[the accessibility level] of the view designated by the actual".
This is an incorrect intepretation, as the AARM points out.  Instead,
the AARM, in a "To be honest" section, makes it clear that if the
actual parameter for an access parameter is an expression of a named
access type, the accessibility level of the anonymous access type is
the same as that of the named access type, not that of the
"designated" view.

If anyone is already looking for evidence that RM95 3.10.2(13) needs
to be rewritten because the current wording could trip up someone who
trusts the RM, please consider this to be such evidence.

In any case, in the above example, the accessibility level of the
anonymous access parameter will be that of the type Pak1.Object_Class
(which is library level), not that of X1.  So it would be expected
that no Program_Error should be raised.

I tried a similar case with the type of H3 being a named access type
declared inside Test87.  When compiled with GNAT, the program raises
Program_Error, even when the prefix of 'Unchecked_Access is itself a
library-level object.  This is what I would have expected.  So it
appears GNAT does not follow the second interpretation after all.

> would still have an accessibility level of "inside
> Test87", and the type conversion inside P1 would thus be illegal
> (4.6(48)).  Using the second interpretation, 'Unchecked_Access would
> create a "special" access value that appears to designate an object
> declared immediately within a library package, and this access value
> would eventually be passed to P1, making the accessibility level of O
> library level, making the type conversion legal.

My apologies for posting my previous question too quickly.

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


Questions? Ask the ACAA Technical Agent