Version 1.2 of ais/ai-00275.txt

Unformatted version of ais/ai-00275.txt version 1.2
Other versions for file ais/ai-00275.txt

!standard 12.05.03 (08)          01-09-20 AI95-00275/01
!class binding interpretation 01-09-20
!status work item 01-09-20
!status received 01-09-18
!qualifier Error
!priority Medium
!difficulty Medium
!subject Aliased components and generic formal arrays
!summary
If a generic formal array type does not have aliased components, neither must the actual type.
!question
Defect Report 8652/0008 (4.6(12.1/1)) includes a rule which forbids view conversions between array types if one array has aliased components and the other doesn't. However, there needs to be a similar rule for actual/formal matching in generic instantiations. Otherwise, it is possible to use a generic to circumvent 4.6(12.1/1).
!recommendation
(See summary.)
!wording
(See corrigendum.)
!discussion
Without this rule it is possible to violate the constrained status of aliased array components.
Consider (adapted from the example in AARM 4.6(12.a.1-3/1)):
generic type T is private; type A is array (1 .. 10) of T; Obj : in T; package Gen is procedure S (Y : in out A); end Gen;
package body Gen is procedure S (Y : in out A) is begin Y(1) := Obj; end S; end Gen;
package P is type T is private; A : constant T; type A1 is array (1 .. 10) of aliased T; private type T (D : Integer := 0) is null record; A : constant T := (D => 1); end P;
with P, Gen; procedure Prob is X : P.A1; package Inst is new Gen (P.T, P.A1, A); begin S (X); -- This call will change the discriminant of X(1), -- so we cannot allow the instantiation. end Prob;
!corrigendum 12.05.03(08)
Replace the paragraph:
by:
!ACATS test
Existing ACATS tests should be modified to require this rule, and to eliminate any cases which test that this is allowed.
!appendix

From: Pascal Leroy
Date: Tuesday, September 18, 2001, 10:37 AM

> package Interfaces.C.String_Lists is  -- or some other name.
>   new Interfaces.C.Pointers( Index         => size_t,
>                              Element       => chars_ptr
>                              Element_Array => chars_ptr_array,
>                              Terminator    => null_ptr );

This instantiation got me thinking on a totally unrelated issue.

The formal array type Element_Array has aliased components, chars_ptr_array
doesn't (in the language as it stands today).

In TC1, we have a rule (4.6(12.1/1)) which forbids view conversions between
array types if one array has aliased components and the other doesn't.  But it
seems to me that we should also have a similar rule for actual/formal matching
in generic instantiations.  Otherwise, it is possible to use a generic to
circumvent 4.6(12.1/1).

Or am I missing something?

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

From: Randy Brukardt
Date: Tuesday, September 18, 2001, 11:44 AM

> In TC1, we have a rule (4.6(12.1/1)) which forbids view conversions between
> array types if one array has aliased components and the other doesn't.  But it
> seems to me that we should also have a similar rule for actual/formal matching
> in generic instantiations.  Otherwise, it is possible to use a generic to
> circumvent 4.6(12.1/1).

Well, we already have 12.5.3(8): "If the formal type has aliased components,
then so shall the actual."

But it appears that an formal type with unaliased components could match an
actual type with aliased components, thus not only circumventing 4.6(12.1/1),
but actually requiring the wrong behavior.

The question is whether changing 12.5.3(8) to require matching of the aliased
component property is an unacceptible incompatibility. (If so, we could define
a "run-time" check that would always be detected at compile-time for
non-sharing implementations.)

> Or am I missing something?

I don't think so.

Note that 12.5.3(8) makes it impossible to instantate Interfaces.C.Pointers
with Chars_Ptr_Array. So it doesn't work for the use described in the comment.

(I must say that I don't find the comment very convincing. The point of the
standard packages is to provide building-blocks that a user couldn't easily
program themselves - for instance, Interfaces.C.Short because its not obvious
what the representation of the C type is, Interface.C.To_C because its not
certain that the representation of C and Ada strings are the same, etc. In a
case like this where there is no barrier to programming the type themselves, it
simply clutters the package. I know that I never go looking in the predefined
packages to see if there is a type that might help; I only do so when there is
a solid reason for doing so.)

Anyway, I take it that at least two ARG members here are calling for an AI??

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

From: Pascal Leroy
Date: Wednesday, September 19, 2001, 4:12 AM

I am certainly calling for an AI to fix the actual/formal matching rule, as it
is clearly a hole in the language.

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

From: Erhard Ploedereder
Date: Sunday, October 10, 2002, 11:46 AM


Ignore this, unless AI-275 or AI-295 are on your plate.

Here are fixed-up versions of program examples in the two AIs, which
I compiled at the meeting.

Erhard
-----------------------------


procedure Test275 is

   type Short_Int is range 1..10;

   generic
      type T is private;
      type A is array (Short_Int) of T;
      Obj : in T;
   package Gen is
      procedure S (Y : in out A);
   end Gen;

   package body Gen is
      procedure S (Y : in out A) is
      begin
         Y(1) := Obj;
      end S;
   end Gen;

   package P is
      type T is private;
      A : constant T;
      type A1 is array (Short_Int) of aliased T;
   private
      type T (D : Integer := 0) is null record;
      A : constant T := (D => 1);
   end P;

   X: P.A1;

   package body P is
      type Ptr is access all T;
      subtype CPtr is Ptr(1);
      Y: Ptr := X(1)'Access;
      Z: CPtr := Y;
   end P;

   -- with P, Gen;
   procedure Prob is
      package Inst is new Gen (P.T, P.A1, P.A);
   begin
      Inst.S (X); -- This call will change the discriminant of X(1),
      -- so we cannot allow the instantiation.
   end Prob;
begin
   null;
end Test275;

[See !appendix of AI-00295 for Test295.]

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

Questions? Ask the ACAA Technical Agent