This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [Patch, fortran] PR25746 - elemental subroutine dependency checking - redux


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



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]