Version 1.1 of ai22s/ai22-0030-1.txt

Unformatted version of ai22s/ai22-0030-1.txt version 1.1
Other versions for file ai22s/ai22-0030-1.txt

!standard 5.5.2(6.1/4)          22-01-25 AI22-0030-1/01
!class binding interpretation 22-01-25
!status work item 21-06-04
!status received 21-04-28
!priority Low
!difficulty Easy
!qualifier Omission
!subject Array iterators of slices
!summary
The object of an array or container iterator must allow renaming.
!question
In the 8.5.1 rules for renaming, we have a special rule about slices:
A slice of an array shall not be renamed if this restriction disallows renaming of the array.
In 5.5.2(6.1/4), that seems to be missing.
Is this a problem? (Yes.)
!recommendation
(See Summary.)
!wording
Replace 5.5.2(6.1/4):
The iterator_name or iterable_name of an iterator_specification shall not denote a subcomponent that depends on discriminants of an object whose nominal subtype is unconstrained, unless the object is known to be constrained.
with:
The iterator_name or iterable_name of an iterator_specification shall denote an object for which renaming is allowed.
!discussion
The wording "denotes an object for which renaming is allowed" (or a variant of it) is used in 8.5.4(5.3/5)m 12.4(7), and 12.6(8.4/5). We conclude that it should be used here as well -- it makes the intent clearer and also "future-proofs" this wording as it will adjust for any future changes to the renaming rules.
!example
procedure Foo is subtype Index is Integer range 1 .. 100; type Float_Vec is array (Index) of Float; type Int_Vec is array (Index) of Integer;
type Rec (Has_Ints : Boolean := True) is record case Has_Ints is when False => Floats : Float_Vec; when True => Ints : Int_Vec; end case; end record;
X : Rec := (Has_Ints => True, Ints => (others => 0)); begin for E of X.Ints (1 ..10) loop -- (1) X := (Has_Ints => False, Floats => (others => 1234.5)); -- (2) E := E + 1; end loop; end Foo;
The new rule makes (1) illegal, while the previous rule allowed (1). However, if (1) is allowed, the assignment to X means that X.Ints ceases to exist during the first iteration of the loop. Further iterations would continue to use the now nonexistent array, which would not be good.
!corrigendum 5.5.2(6.1/4)
Replace the paragraph:
The iterator_name or iterable_name of an iterator_specification shall not denote a subcomponent that depends on discriminants of an object whose nominal subtype is unconstrained, unless the object is known to be constrained.
by:
The iterator_name or iterable_name of an iterator_specification shall denote an object for which renaming is allowed.
!ACATS test
An ACATS B-Test should test a case like the example (perhaps add this to an existing test for 5.5.2(6.1/4)).
!appendix

From: Stephen Baird [privately]
Sent: Tuesday, November 30, 2021  5:19 PM

In the 8.5.1 rules for renaming, we have a special rule about slices:

   A slice of an array shall not be renamed if this restriction disallows 
   renaming of the array.


In 5.5.2(6.1), that seems to be missing.


Is this a (tiny) problem?


Note how 12.4(7) manages to deal with this via a dubious technique:
    For a generic formal object of mode in out, the actual shall be a name
    that denotes a variable for which renaming is allowed (see 8.5.1).


All of this taken together suggests  to me that we ought to define the notion 
of a "renamable" object name (probably in 8.5.1) and then use this term in all
three places. Or we could copy the 12.4(7) cheat in 5.5.2, but I don't much
like that idea. Although I do like it better than adding a sentence about
slices in 5.5.2 .

What do you think?

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

From: Randy Brukardt [privately]
Sent: Wednesday, December 1, 2021  2:24 AM

I think this approach would make sense. Doesn't the prefix of 'Access follow the 
same rules? What does 3.10.2 say about that (my browser just crashed, else I'd
look myself)?

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

From: Stephen Baird [privately]
Sent: Wednesday, December 1, 2021  11:28 AM

This is not a problem for 'Access because slices are never aliased.

But I agree, if we introduce a  new term then we should also use it in 3.10.2 .

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

From: Randy Brukardt [privately]
Sent: Wednesday, December 1, 2021  3:16 PM

Do you have an example of how this could be a problem? We'll need some example
for the AI. I could probably figure it out, but it's always better to make the
questioner come up with it. 

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

From: Stephen Baird [privately]
Sent: Wednesday, December 1, 2021  4:34 PM

GNAT accepts the following example.

procedure Foo is
   subtype Index is Integer range 1 .. 100;
   type Float_Vec is array (Index) of Float;
   type Int_Vec is array (Index) of Integer;

   type Rec (Has_Ints : Boolean := True) is
      record
         case Has_Ints is
            when False => Floats : Float_Vec;
            when True => Ints : Int_Vec;
         end case;
      end record;
   
   X : Rec := (Has_Ints => True, Ints => (others => 0));
begin
   for E of X.Ints (1 ..10) loop
      X := (Has_Ints => False, Floats => (others => 1234.5));
       --  at this point X.Ints no longer exists
      E := E + 1;
   end loop;
end Foo;

If you remove the "(1 ..10)" then GNAT rejects the example with an appropriate
message:
   error: iterable name cannot be a discriminant-dependent component of a mutable object

I believe this is consistent with the current RM wording.
This is a problem - the RM should require rejecting both versions.

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

From: Randy Brukardt [privately]
Sent: Wednesday, December 1, 2021  4:47 PM

Thanks. And agreed. I think we could fix *this* problem by adding "(or slice of
such a subcomponent)" appropriately, but it is reasonable to consider a fix that
wouldn't get broken in the future by further fixes in this area (given how many
times the underlying rules have been "fixed", it wouldn't surprise me if that
continued).

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

From: Randy Brukardt [privately]
Sent: Tuesday, January 25, 2022  6:24 PM

> Or we could copy the 12.4(7) cheat in 5.5.2, but I don't much like that idea. 
 
FYI, We already did that in 8.5.4(5.3/5) and 12.6(8.4/5), so there are at 
least three instances of "renaming is allowed" in the RM. I conclude that *is*
the term in question, and we should use that in 5.5.3(6.1/3). Inventing a new
term would just be churn.

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

Questions? Ask the ACAA Technical Agent