!standard 5.5.2(8/3) 23-06-26 AI22-0025-1/03 !standard 5.5.2(10/5) !class ramification 22-01-20 !status Corrigendum 1-2022 23-06-26 !status ARG Approved 8-0-0 23-06-11 !status work item 22-01-20 !status received 22-05-14 !priority Low !difficulty Easy !subject Accessibility of generalized iterators !summary There is only a single loop parameter object for a (sequential) generalized iterator; similarly, there is only one loop parameter object for each thread of a parallel generalized iterator. !issue Does the RM make it clear that the execution of a loop statement with a generalized iterator does not have a single loop parameter object that takes on different values; that is, does each iteration get its own loop parameter object? (No.) Contrast this with AARM 5.5.2(8.a/5): The loop parameter of a generalized iterator has the same accessibility as the loop statement. This means that the loop parameter object is finalized when the loop statement is left. (It also may be finalized as part of assigning a new value to the loop parameter.) That wording, at least taken in isolation, would seem to suggest that the loop parameter is finalized even if there are no iterations. (It is.) More importantly, this suggests that if the value of Some_Part_Of_The_Loop_Parameter'Unchecked_Access is generated in one iteration and then dereferenced in the next iteration, then this does not trigger the 13.11.2 rule Evaluating a name that denotes a nonexistent object ... is erroneous. But it should. That is, such an execution should be erroneous. (It is not.) The accessibility level for a loop parameter of a generalized iterator should be that of one loop iteration, not that of the entire loop statement (that is, all iterations). Is a fix required? (No.) !recommendation (See Summary.) !discussion [Editor's note: This AI was created so that all of the deferred WG 9 review issues were handled somewhere.] The model indeed was that there is a single loop object that takes on different values during the iteration. The legality rule requiring the cursor type to be nonlimited (5.5.2(6.3/4)) ensures that the cursor can be copied into the iteration object. The Dynamic Semantics of a generalized iterator as given in 5.5.2(10/5) make it clear that a single loop parameter object is created, and the various values produced by the iteration are assigned into it. Similar rules apply to parallel generalized iterators -- there is one loop parameter per thread. For a cursor type that requires finalization, the normal finalization of the loop object is performed. Note that the loop parameter object is initialized with the result of the call to First (or Last); it is never empty. So an iteration that stops immediately still has written a value to the loop parameter (it is a value that returns Has_Element equals False), and thus that value still needs finalization. Thus, the premise of the question is wrong, and so therefore are the consequences. A related topic was covered in AI12-0093-1; the discussion of that AI is clear that we only want a single loop parameter object. AI12-0120-1 also is clear that an assignment is implied by the Dynamic Semantics, and thus a limited cursor cannot be allowed. !ACATS test Since there is no change here, no additional tests are needed. !appendix From: Steve Baird WG 9 Review issue #139 - May 14, 2021 Looking more closely at value_sequences involves looking at iterated_element_associations. And that leads to wondering about whether the accessibility level is well defined for the loop parameter of such an iteration. Consider this expression: [for Loop_Param of ... => Loop_Param.Aliased_Component'Access]'Reduce (Function_With_Anonymous_Access_Parameter, Init_Value) When Function_With_Anonymous_Access_Parameter is called (at runtime), an accessibility level will need to be passed in. What rules define that level? Perhaps the apparently-missing accessibility level definition follows from some equivalence rule, but I don't see it. If there is an issue here, then (at least) two solutions come to mind. One approach is to make sure this case is well-defined in 3.10.2. Alternatively, we could require that the Value_Type and the Accum_Type of a reduction expression shall each not be an anonymous access type. Is there a similar issue with quantified expressions? Perhaps not (although it seems suspicious that 5.5.2(8.a/5) talks about "the loop statement", as opposed to other looping constructs). This is a little off the subject of 4.5.10, but there seems to be a related accessibility problem with generalized iterators. The RM is not as clear as I feel it should be that the execution of a loop statement with a generalized iterator does not have a single loop parameter object that takes on different values; each iteration gets its own loop parameter object (or at least it should). Contrast this with RM 5.5.2: 8.a/5 The loop parameter of a generalized iterator has the same accessibility as the loop statement. This means that the loop parameter object is finalized when the loop statement is left. (It also may be finalized as part of assigning a new value to the loop parameter.) That wording, at least taken in isolation, would seem to incorrectly suggest that the loop parameter is finalized even if there are no iterations. More importantly, this suggests that if the value of Some_Part_Of_The_Loop_Parameter'Unchecked_Access is generated in one iteration and then dereferenced in the next iteration, then this does not trigger the 13.11.2 rule Evaluating a name that denotes a nonexistent object ... is erroneous. But it should. That is, such an execution should be erroneous. And similarly for 13.11.2 (15.2/4). The accessibility level for a loop parameter, at least in this case, should be that of one loop iteration, not that of the entire loop statement (i.e., all iterations). OTOH, if we are iterating over the elements of an array with an array component iterator then we want the accessibility level of the element to be that of the array. **************************************************************** From: Randy Brukardt WG 9 Review issue #139 - May 29, 2021 This can't possibly be something that is going to matter to 99.99% of reduction expressions, so resolving this sort of corner case can wait for a future Ada. (Preferably about Ada 2222. :-) Marked as deferred. **************************************************************** Editor's note, January 20, 2022 The reduction expression issue was handled by making anonymous access parameters illegal; this was one of the topics of AI22-0011-1. However, the (off-topic) issues raised about generalized iterators need to be addressed. ****************************************************************