https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107819

--- Comment #6 from Mikael Morin <mikael at gcc dot gnu.org> ---
(In reply to anlauf from comment #5)
> (In reply to Mikael Morin from comment #4)
> > But is it required to generate a temporary?
> > As I understand it, the code is invalid, and (correctly) diagnosed, so there
> > is nothing else to do.
> > It's invalid because of 15.5.2.13 Restrictions on entities associated with
> > dummy arguments:
> > (4) If the value of the entity or any subobject of it is affected through
> > the dummy argument, then at any time during the invocation and execution of
> > the procedure, either before or after the definition, it shall be referenced
> > only through that dummy argument unless (...)
> 
> Right.
> 
> I was confused by two observations.  First, NAG & Cray seem to generate
> temporaries, while Intel and NVidia don't and would agree with gfortran
> after the patch.
> 
> Second, I stumbled over:
> 
> ! 15.5.2.3 Argument association
> ! (4) A present dummy argument with the VALUE attribute becomes argument
> ! associated with a definable anonymous data object whose initial value is
> ! the value of the actual argument.
> 
Ouch! You're right, this makes the part I quoted above irrelevant.
And it explicitly asks for a temporary.

> So it boils down to what ELEMENTAL actually means in that context.  F2018:
> 
> 15.8.3 Elemental subroutine actual arguments
> 
> ! In a reference to an elemental subroutine, if the actual arguments
> ! corresponding to INTENT(OUT) and INTENT(INOUT) dummy arguments are
> ! arrays, the values of the elements, if any, of the results are the same
> ! as would be obtained if the subroutine had been applied separately, in
> ! array element order, to corresponding elements of each array actual
> ! argument.
> 
> So I read this that
> 
>    call s (a(n), a)
> 
> is to be interpreted as
> 
>   do i = 1, size (a)
>      call s (a(n(i)), a(i))
>   end do
> 
> and this would actually be well-defined behavior... ;-)

With your quote from 15.5.2.3 above, it would be more like:
do i = 1, size(a)
  tmp(i) = a(n(i))
end do
do i = 1, size(a)
  call s(tmp(i), a(i))
end do

Reply via email to