[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