Skip to content

[Flang] transfer of a derived type with a pointer component #122216

@kawashima-fj

Description

@kawashima-fj

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 program

Output 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    flang:runtimequestionA question, not bug report. Check out https://llvm.org/docs/GettingInvolved.html instead!

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions