[Patch, fortran] PR25746 - elemental subroutine dependency checking - redux
Brooks Moses
bmoses@stanford.edu
Mon Apr 24 22:10:00 GMT 2006
Paul Thomas wrote:
> In the case of an INTENT(INOUT) argument, the original data has to be
> packed and copied to the temporary. I have signalled a TODO here; the
> potential creation of two temporaries could be eliminated and this is
> something that I intend to contribute after I have fixed the array
> TRANSFER intrinsic. This will require a new library routine that can be
> employed here. In the mean time, this patch works correctly (I hope!),
> even if it is a bit inefficient in a small number of cases.
As discussed in the thread "question about elemental subroutines", the
test cases for this part of the patch are illegal code. Specifically,
as per 12.4.1.6 of the F95 standard, if two dummy arguments are
associated with the same actual argument, then neither one of the dummy
arguments can legally be modified within the subroutine. And, as per
12.7.2, this restriction applies to calls to elemental subroutines just
as it would to any other subroutine.
I think, though I'm not certain, that this is not just a flaw of the
test cases, but a flaw of this entire portion of the patch -- it solves
a problem that can only occur in illegal code. (And it's a case for
which, as Dominique pointed out, the "correct" result would be ambiguous
if it were legal.) Thus, in my opinion, gfortran should not be
"solving" this problem by adding complication to the code....
This illegal situation would also apply to cases with INTENT(OUT)
arguments as well as INTENT(INOUT) arguments. I'm not sure what
properly ought be done about those, however, as those can be associated
with expressions as well as variables, and there's a possibility of
legal dependencies there. As, for instance, occurs in the assignment
statements of the rest of the testcase -- note that
x(1:2) = x(2:3)
(with x a derived type with a user-defined assignment operator) maps to
myassign(x(1:2), (x(2:3)))
where the second argument is in parentheses, and thus the dummy argument
is associated with an expression result rather than with x(2:3) itself.
I've quoted the relevant portions of the testcase below, for reference.
> +! Check an INTENT(INOUT) case
> + call nonassign (x, x((/2,3,1,4,5,6/)))
> + if (any(x%x .ne. (/-96000, 7200, -48000, -24, -480, 6000000/))) call abort ()
> +! ...and again
> + call nonassign (x(2:3), x(1:2))
> + if (any(x%x .ne. (/-96000, 288000, -21600, -24, -480, 6000000/))) call abort ()
> +contains
> + elemental subroutine nonassign(x,y)
> + type(mytype), intent(INout) :: x
> + type(mytype), intent(in) :: y
> +! Change the sign according to the input, to verify that INOUT is working.
> + if (x%x > 20000) then
> + x%x = y%x*3
> + else
> + x%x = -y%x*3
> + end if
> + end subroutine nonassign
> +end program test
- Brooks
More information about the Fortran
mailing list