Version 1.4 of ais/ai-00168.txt

Unformatted version of ais/ai-00168.txt version 1.4
Other versions for file ais/ai-00168.txt

!standard 04.06 (00)          99-02-23 AI95-00168/03
!class binding interpretation 96-11-16
!status work item 98-04-04
!status received 96-11-16
!priority Medium
!difficulty Easy
!subject Aliased objects cannot have discriminants modified
!summary 99-02-23
A view conversion is illegal if the target subtype and the operand do not have both aliased components or both non-aliased components.
A discriminant constraint for a general access type is illegal if the designated subtype is a private type with default discriminants, but the partial view has no discriminants.
!question 98-04-04
Consider the following code fragment:
package P is pragma Elaborate_Body; type T is private; A : constant T; private type T (D : Integer := 0) is null record; type Ptr is access all T; A : constant T := (D => 1); end P;
with P; package Q is type A1 is array (1 .. 10) of aliased P.T; type A2 is array (1 .. 10) of P.T; X : A1; end Q;
with P, Q; procedure R is procedure S (Y : in out Q.A2) is begin Y (1) := P.A; end; begin S (Q.A2 (Q.X)); -- This call will change the discriminant of Q.X (1) end;
This example illustrates a case where it is possible to change the discriminant of an aliased component of an object, which is supposed to be forbidden.
!recommendation 98-04-04
(See wording.)
!wording 98-04-04
Add the following clause after RM95 4.6(12):
In a view conversion for an array type, the target type and the operand type shall either both have aliased components, or both have non-aliased components.
Add the following clause after RM95 3.7.1(7):
A discriminant_constraint is not allowed in a subtype_indication whose subtype_mark denotes a general access subtype whose designated subtype is a private type with defaulted discriminants, if the partial view of the private type has no discriminants.
!discussion 98-04-04
The problem (1) comes from the fact that it is possible to use a view conversion to convert an array object with aliased components to an array type with non-aliased components. Such a conversion must be disallowed.
At the Henley meeting, the following case was also discussed:
with Q; package body P is PT : Ptr (0) := Q.X (1)'access; begin Q.X := (others => (D => 2)); -- Changes the discriminant of Q.X (2) end P;
The root of problem (2) is that the partial view of P.T is constrained, but the full view isn't. This causes privacy problems when applying the following rule:
"if a component_definition contains the reserved word aliased and the type of the component is discriminated, then the nominal subtype of the component shall be constrained." (RM95 3.6(11))
One way to fix this problem would be to require a component-by-component check on the assignment to Q.X, but that would be very expensive. Moreover, a compile-time check would clearly be better than a run-time check.
Aliased-ness of the components is not really what is causing trouble, though. It is really the existence of a general access type, and in fact of a discriminant constraint on such an access type, which causes trouble. Thus, forbidding such a constraint seems like the right solution, especially considering that constraints on access types are not a terribly useful feature.
!appendix

!section 4.6(00)
!subject Aliased objects can have discriminants modified
!reference RM95-4.6
!reference RM95-6.4.1 (16,17)
!from Stephen Michell 96-10-12
!keywords constrained object aliased change of discriminat
!reference 96-5720.a Steve Michell 96-10-12>>
!discussion

Consider the following code fragment

       procedure acc_cvt2 is
         package P is
           type T is private;
           a: constant T;
           b: constant T;
         private
           type T( X: integer := 0 ) is null record;
           a: constant T := ( X => 1 );
           b: constant T := ( X => 2 );
         end P;
         type A is array( 1 .. 10) of aliased P.T;
         type B is array( 1 .. 10) of P.T;
         X : A := (1..10 => P.a);
         procedure Q( Y : in out B ) is
         begin
           Y(1) := P.B;
         end Q;
       begin
         Q(B(X));
       end ACC_CVT2;

Object X is constrained because it is an array of aliased records, even
though unaliased objects of such a type would be unconstrained. The call
Q(B(X)) is a view conversion by 4.6(5). The remaining rules in 4.6
do not appear to cover the case shown above, but it appears that a view
conversion between an unconstrained and constrained view of an object
should be illegal.

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


Questions? Ask the ACAA Technical Agent