Version 1.4 of ai05s/ai05-0087-1.txt

Unformatted version of ai05s/ai05-0087-1.txt version 1.4
Other versions for file ai05s/ai05-0087-1.txt

!standard 7.5(5/2)          08-04-18 AI05-0087-1/03
!standard 12.5.1(5.1/2)
!class binding interpretation 08-01-30
!status WG9 Approved 08-06-20
!status ARG Approved 8-0-1 08-02-10
!status work item 08-01-30
!status received 08-01-23
!priority Low
!difficulty Medium
!qualifier Omission
!subject Formal nonlimited derived types should not have limited actual types
!summary
Formal nonlimited derived types should not have limited actual types.
A class-wide type is limited if its specific type is limited.
!question
It appears that we can use formal derived types derived from a limited interface to copy tasks and other limited objects. Consider:
declare type Ifc is limited interface;
generic type T is abstract new Ifc with private; -- T is nonlimited: 7.5(6.1/2) procedure Classwide_Store (Target : out T'Class; Source : T'Class);
procedure Classwide_Store (Target : out T'Class; Source : T'Class) is begin Target := Source; end Classwide_Store;
procedure Store is new Classwide_Store (Ifc); -- legal? (No.)
task type Tsk; task body Tsk is begin null; end Tsk;
type Has_Task is limited new Ifc with record F : Tsk; end record;
X, Y : Has_Task; begin Store (X, Y); end;
Is the instantiation legal? (No.)
7.5(3-7) seems to imply that most class-wide types are nonlimited, even if the specific type is limited. That is a change from Ada 95; was this intended? (No.)
!recommendation
(See Summary.)
!wording
Replace the deleted paragraph 7.5(5/2) with:
* a class-wide type whose specific type is limited;
Change 12.5.1(5.1/2) as follows:
The actual type for a formal derived type shall be a descendant of the ancestor type and every progenitor of the formal type. {If the formal type is nonlimited, the actual type shall be nonlimited.} If the reserved word synchronized appears in the declaration of the formal derived type, the actual type shall be a synchronized tagged type.
AARM Discussion: A type derived from a limited interface could be nonlimited; we do not want a limited type derived from such an interface to match a nonlimited formal derived type. (Otherwise, we could assign limited objects.)
!discussion
There was no intent that the class-wide type associated with a limited specific type be nonlimited; that would open up ways to assign tasks and the like. So we add explicit wording clarifying that class-wide types are limited if their specific type is.
We certainly don't want the example in the question to be legal, so we must add wording to prevent that.
!corrigendum 7.5(4/2)
Insert after the paragraph:
!corrigendum 12.5.1(5.1/2)
Replace the paragraph:
The actual type for a formal derived type shall be a descendant of the ancestor type and every progenitor of the formal type. If the reserved word synchronized appears in the declaration of the formal derived type, the actual type shall be a synchronized tagged type.
by:
The actual type for a formal derived type shall be a descendant of the ancestor type and every progenitor of the formal type. If the formal type is nonlimited, the actual type shall be nonlimited. If the reserved word synchronized appears in the declaration of the formal derived type, the actual type shall be a synchronized tagged type.
!ACATS Test
A B-Test like the example in the question should be tried.
!appendix

From: Stephen W. Baird
Sent: Wednesday, January 23, 2008  5:43 PM

We don't want to allow a limited type to be specified as the actual
parameter corresponding to a nonlimited formal type in an instantiation.

There may be a hole in this area in the case of a formal type
which is derived from a limited interface type.

I didn't find RM wording to justify rejecting the following example:

  declare
        type Ifc is limited interface;

        generic
            type T is abstract new Ifc with private; -- T is nonlimited: 7.5(6.1/2)
        procedure Classwide_Store (Target : out T'Class; Source : T'Class);

        procedure Classwide_Store (Target : out T'Class; Source : T'Class) is
        begin
            Target := Source;
        end Classwide_Store;

        procedure Store is new Classwide_Store (Ifc); -- legal?

        task type Tsk;
        task body Tsk is
        begin
            null;
        end Tsk;

        type Has_Task is new Ifc with
            record
                F : Tsk;
            end record;

        X, Y : Has_Task;
    begin
        Store (X, Y);
    end;

I also didn't  find the general rule (whose existence I had always assumed)
that a class-wide type is limited iff the corresponding specific type is 
limited. An unfriendly reading of 7.5 could suggest that if a specific limited
type has no limited components, then the corresponding class-wide type is not
limited. Is this just an oversight, or am I missing something?

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

From: Tucker Taft
Sent: Wednesday, January 23, 2008  7:32 PM

Good point.  RM 12.5.1(5.1/2) should probably be revised
roughly as follows:

     The actual type for a formal derived type shall be a
     descendant of the ancestor type and every progenitor
     of the formal type.  {If the formal type is nonlimited,
     the actual type shall be nonlimited.}  If the reserved
     word synchronized appears in the declaration of the
     formal derived type, the actual type shall be a
     synchronized tagged type.


> ...
> I also didn't  find the general rule (whose existence I had always assumed)
> that a class-wide type is limited iff the corresponding specific type is limited.
> An unfriendly reading of 7.5 could suggest that if a specific limited type has no
> limited components, then the corresponding class-wide type is not limited.
> Is this just an oversight, or am I missing something?

Another good point.  7.5(3) used to say "a descendant of ..." but
that was deleted for Ada 2005.  It turns out that classwide
types are descendants of their root type, and that is how
they were covered.  Having deleted that phrase, we need
to add back an explicit mention of classwide types.
Hence, a bullet at the end is needed, saying something like:

    * a class-wide type whose associated specific type is limited.

(plus the usual replacement of the preceding bullet's "."
with a ";")

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


Questions? Ask the ACAA Technical Agent