PR15809 and pointer array aliassing
Paul THOMAS
paulthomas2@wanadoo.fr
Fri Nov 25 13:54:00 GMT 2005
One of the reduced examples for this PR is
SUBROUTINE A(p,LEN)
CHARACTER(LEN=LEN), DIMENSION(:), POINTER :: p
IF ( .NOT. ASSOCIATED(p) ) THEN
END IF
END SUBROUTINE A
which would ICE in gfc_trans_deferred_array, at the assertion that the backend_decl should be a VAR_DECL. As Erik Edelmann demonstrated, this can be fixed by allowing PARM_DECLs as well. Going on to use the automatic character length, dummy pointer arrays for something purposeful, introduces a faintly alarming problem, which has a fix, and a more fundamental one that I have already mentioned several times on the list.
The alarming but easily fixable problem is that the elements of p have a null TYPE_UNIT_SIZE so that the descriptor dtype, when it is built, does not include the size of the object. By and large this is OK until an assignment or IO is attempted and an ICE ensues. I will submit a patch for this problem shortly.
The second problem is harder to fix. If I have interpreted the standard correctly, the above declaration should be interpreted as p being an alias for (or being aliassed by?) the caller's array. This being so, the size of the elements of the array must be respected, to the extent that the start address of each element of the array must be the same in each scope. Thus, an implicit parameter that must be passed and returned is the "size" of the target elements, as well as the "size" of the elements in the local scope.
I now know of four situations, where this feature is needed in gfortran:
(i) Pointer assignment to an array of type, from an array of derived types, with a component of type. eg.
i(:) = d(:)%i
(ii) Using an array of derived types, with a component of type, as an actual argument, where the formal argument is an array of type. eg
call foo (d(:)%i)
......
subroutine foo (ia)
<type>, dimension(:) :: ia
......
This, of course, is very similar to (i).
(iii) Automatic character length, pointer dummy arguments (ie. PR15809). eg.
character(4), dimension (:), pointer :: ptr
......
call a (ptr, 6) ! a has the interface of the subroutine at the top of the page
......
(iv) Pointer assignments between arrays with different character lengths. eg.
character(10), dimension(:), pointer :: c1
character(12), dimension(:), pointer :: c2
allocate (c1(2))
c1 = "abcdefghij"
c2 => c1
print *, c1(1)
print *, c2(2)
end
for this, gfortran gives:
abcdefghij
cdefghij%
whereas, DF6.0 gives:
abcdefghij
abcdefghij
DF6.0 has a small bug, in that the result of reducing the character(12) array to character(8) is
abcdefghij
abcdefgh
but the start addresses are coming out correctly, at least.
I believe that it is correct to say that array aliassing could be introduced gradually to gfortran by adding a target size field to array descriptors that could be ignored in the first instance. Then, the step could taken of setting its value in each of the above situations (+ others ?). Finally, the users of array descriptors could be modified to make use of this new field. If we proceed in this fashion, I rather think that this feature could be added to gfortran painlessly; ie. each stage could be extensively regtested and tested "in the field" before proceeding to the next.
Any comments?
Cheers
Paul
More information about the Fortran
mailing list