-
Notifications
You must be signed in to change notification settings - Fork 15.4k
Description
When an object of a derived type with a pointer component is used as source of the transfer function, the result object has a size of the pointee but contains the pointer address .
type :: box
type(data), pointer :: ptr
end type
type(box) :: box1
dest = transfer(box1, dest)Full reproducer:
program main
use, intrinsic :: iso_c_binding
use, intrinsic :: iso_fortran_env
implicit none
type :: data
integer(kind=4), dimension(10) :: array
end type
type :: box
type(data), pointer :: ptr
end type
integer :: i, len
integer(kind=4), pointer :: ptr1
type(data), target :: data1
type(box) :: box1
integer(kind=4), dimension(:), allocatable :: dest
do i = 1, 10
data1%array(i) = i
end do
box1%ptr => data1
len = size(transfer(box1, dest))
allocate(dest(len))
dest = transfer(box1, dest)
write(6, *) '# len'
write(6, '(I4)') len
write(6, *) '# ptr1 data1 box1'
write(6, '(I4)') storage_size(ptr1)
write(6, '(I4)') storage_size(data1)
write(6, '(I4)') storage_size(box1)
write(6, *) '# transfer'
write(6, '(I4)') storage_size(transfer(box1, dest))
write(6, '(I4)') size(transfer(box1, dest))
write(6, *) '# dest'
write(6, '(I4)') storage_size(dest)
write(6, '(I4)') size(dest)
write(6, *) '# data1'
write(*, '(Z17.16)') transfer(c_loc(data1), 0_int64)
write(6, *) '# array'
do i = 1, len
write(*, '(Z9.8)') dest(i)
end do
end programOutput of Flang (20.0.0git f4230b4) on AArch64:
# len
10
# ptr1 data1 box1
32
320
320 **(3)**
# transfer
32
10
# dest
32
10 **(1)**
# data1
0000AAAACC920580
# array
CC920580 **(2)**
0000AAAA **(2)**
00000028
00000000
0134D94F
01012A00
CC91E7D0
0000AAAA
00000000
00000000
Please see (1) and (2). (1) size(transfer(box1, dest)) is 10, which is the size of the pointee array. (2) dest(1)+dest(2) is an address.
Output of GFortran (13.2.0) on AArch64:
# len
2
# ptr1 data1 box1
32
320
64 **(3)**
# transfer
32
2 **(1)**
# dest
32
2
# data1
0000FFFFF67F9728
# array
F67F9728 **(2)**
0000FFFF **(2)**
In GFortran, (1) size(transfer(box1, dest)) is 64, which is the size of an address.
The Fortran standards defines:
Result Value. If the physical representation of the result has the same length as that of SOURCE, the physical representation of the result is that of SOURCE.
Though I don't know what "physical representation" exactly means, the result of GFortran seems correct. At least, the current result of Flang is inconsistent (size is that of pointee but content is a pointer).
Also, (3) storage_size(box1) differs. Flang includes the pointee but GFortran includes only the pointer itself.
The problem was found when I investigated a compilation error of NTPoly.