Version 1.1 of acs/ac-00047.txt

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

!standard 4.6(15)          02-12-05 AC95-00047/01
!standard 4.6(24)
!standard 4.6(42)
!class confirmation 02-12-05
!status received no action 02-08-22
!subject Converting from untagged to tagged type
!summary
!appendix

!topic Converting from untagged to tagged type
!reference AI95-00184, RM95-4.6
!from Adam Beneschan 08-22-02
!discussion

AI95-00184 recognizes the possibility that a type conversion can occur
between an untagged and a tagged type.  Example:

   package Pak1 is
      pragma Elaborate_Body;
      type T is private;
   private
      type T is tagged record
         ...
      end record;
   end Pak1;

   with Pak1;
   package Pak2 is
      type T2 is new Pak1.T1;
   end Pak2;

   with Pak2;
   package body Pak1 is
      V1 : T;
      V2 : Pak2.T2;

      procedure P is
      begin
         V1 := T (V2);
         V2 := Pak2.T2 (V1);
      end P;
   . . .

However, I believe there are a few places in RM95 4.6 where this
possibility is not adequately considered.  Specifically:

4.6(24): "In a view conversion for an untagged type, the target type
shall be convertible (back) to the operand type".  What is a "view
conversion for an untagged type"?  Is it one where the operand is
untagged, where the target is untagged, or where either is untagged?
(I think the last one is correct.  This can occur where an OUT or IN
OUT parameter is involved.)

4.6(42): "The tag of the result is that of the operand."  If the
operand is untagged and the target type is tagged, this clause doesn't
make sense since the operand does not have a tag.  What is the tag of
the result?  (I believe that this can only be an issue if the untagged
type is derived, directly or indirectly, from the partial view of a
type T0 whose full view is tagged; I think that in this case, the tag
of the result should be T0'Tag [T0 being the full view of the type, of
course]).

4.6(15): If the target type is a general access type, then "If the
target designated type is tagged, then the operand designated type
shall be convertible to the target designated type".  I believe this
causes problems if the operand designated type is untagged.  Extending
the example above:

   with Pak2;
   package body Pak1 is
      V1 : T;
      V2 : aliased Pak2.T2;

      type Ptr_T is access all T;
      TP : Ptr_T;

      procedure P is
      begin
         TP := Ptr_T(V2'Access);
      end P;
   . . .

This is legal, since T2 is convertible to T; however, the result would
be that TP, an access to a tagged type, would be pointing to an object
that does not have a tag, creating havoc if TP.all is later treated as
a class-wide type and used for dispatching.  Furthermore, since T2 is
not a record extension, nothing prohibits a record_representation_-
clause from being applied to T2, and then accessing a component of
TP.all wouldn't even produce the right result.

I believe 4.6(15) should be amended: "If the target designated type is
tagged, then the operand designated type shall be tagged, and shall be
convertible to the target designated type".

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

From: Adam Beneschan
Sent: Thursday, August 22, 2002  2:52 PM

I wrote:

>    package Pak1 is
>       pragma Elaborate_Body;
>       type T is private;
>    private
>       type T is tagged record
>          ...
>       end record;
>    end Pak1;
>
>    with Pak1;
>    package Pak2 is
>       type T2 is new Pak1.T1;
>    end Pak2;

. . .

> Furthermore, since T2 is
> not a record extension, nothing prohibits a record_representation_-
> clause from being applied to T2, and then accessing a component of
> TP.all wouldn't even produce the right result.

Uh, sorry, that part was just silly.  Of course you can't put a
record_representation_clause on T2 since you can't even see what the
components are.

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

From: Robert A. Duff
Sent: Saturday, August 24, 2002  5:28 PM

> This is legal, since T2 is convertible to T; however, the result would
> be that TP, an access to a tagged type, would be pointing to an object
> that does not have a tag, creating havoc if TP.all is later treated as
> a class-wide type and used for dispatching.  Furthermore, since T2 is
> not a record extension, nothing prohibits a record_representation_-
> clause from being applied to T2, and then accessing a component of
> TP.all wouldn't even produce the right result.

I think V2 needs to have a tag, at least in implementation terms.
The value of that tag is T'Tag.

I haven't looked at the wording carefully enough to know whether it
supports this interpretation.

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

Questions? Ask the ACAA Technical Agent