allocatable type containing allocatable type with PGF90

the latest pgf90 (pgf90 11.5-0 64-bit target on x86-64 Linux -tp nehalem) is stuck when compiling mod_b.f90

mod_a.f90

module a
    implicit none
    type :: a
        real, dimension(:,:,:), allocatable :: v
    contains
        procedure, pass(this) :: alloc => a_alloc
    end type
contains
    subroutine a_alloc(this)
        implicit none
        class(a) :: this
        
        allocate(this%v(10, 10, 10))
    end subroutine a_alloc
end module a

mod_b.f90

module b
    use a
    implicit none
    
    type :: b
        type(a), dimension(:), allocatable :: as
    contains
        procedure, pass(this) :: alloc => b_alloc
    end type
contains
    subroutine b_alloc(this)
        implicit none
        class(b) :: this
        
        integer :: i
        allocate(this%as(10))
        do i = 1, 10
            call this%as(i)%alloc()
        end do
    end subroutine b_alloc
end module b

when I change ‘allocatable’ to ‘pointer’ in mod_b.f90, it can be compiled. When I put type ‘a’ and type ‘b’ in a single module, it can also be compiled.

It seems to be a bug in pgi fortran compiler.

Hi fgao,

Thanks for the example. This is a known issue and was fixed in the 11.6 compilers.

  • Mat

Thank you for your prompt reply. But I have another problem. I now use the pgfortran 11.8 to compile the code.

mod_a.f90

module a
    type :: a
        real, dimension(:,:,:), allocatable :: v
    contains
        procedure, pass(this) :: alloc => a_alloc
        procedure, pass(this) :: init => a_init
    end type
contains
    subroutine a_alloc(this)
        class(a) :: this
        
        allocate(this%v(10, 10, 10))
    end subroutine a_alloc
    
    subroutine a_init(this)
        class(a) :: this
        
        this%v = 1.0
    end subroutine a_init
end module a

mod_b.f90

module b
    use a
    implicit none

    type :: b
        type(a), dimension(:), allocatable :: as
    contains
        procedure, pass(this) :: alloc => b_alloc
        procedure, pass(this) :: init => b_init
    end type
contains
    subroutine b_alloc(this)
        class(b) :: this
        
        integer :: i
        allocate(this%as(10))
        do i = 1, 10
            call this%as(i)%alloc()
        end do
    end subroutine b_alloc
    
    subroutine b_init(this)
        class(b) :: this
        
        integer :: i
        do i = 1, 10
            call this%as(i)%init()
        end do
    end subroutine b_init
end module b

test.f90

program test
    use a
    use b
    
    type(b) :: bb
    call bb%alloc()
    call bb%init()
end program test

The test program compiled sucessfully, but it causes segment fault when running.

Using pgdebug to debug the code

pgdbg> r
libm.so.6 loaded by ld-linux-x86-64.so.2.
libpthread.so.0 loaded by ld-linux-x86-64.so.2.
librt.so.1 loaded by ld-linux-x86-64.so.2.
libc.so.6 loaded by ld-linux-x86-64.so.2.
Signalled SIGSEGV at 0x4027F2, function b_init, file mod_b.f90, line 27
  0x4027F2:  48 63 9                    movslq (%rcx),%rcx

pgdbg> list
 #22:         subroutine b_init(this)
 #23:             class(b) :: this
 #24:             
 #25:             integer :: i
 #26:             do i = 1, 10
 #27:==>>             call this%as(i)%init()
 #28:             end do
 #29:         end subroutine b_init
 #30:     
 #31:     end module b

pgdbg> print this
{ 
    as    = ERROR: NO TYPE for as 
    as$td = ( integer*4 (1:18), pointer) 0x649770 
    .fake = 0
    .fake = 0
}

pgdbg> print this%as
ERROR: NO TYPE for as

Why does ‘as’ have no type and why its value cannot be printed?

Then I modified test.f90 to do all work through it’s member ‘as’ instead of through the type bound procedure of ‘b’, then the program run successfully.

program test
    use a
    use b
    
    type(b) :: bb
    integer :: i

    allocate(bb%as(10))
    do i = 1, 10
        call bb%as(i)%alloc()
        call bb%as(i)%init()
    end do
end program test

and I can print the ‘as’ of bb

pgdbg> p bb
{ 
    as    = ( type(a) (-1395399808:0), pointer) 0x0 
    as$td = ( integer*4 (1:18), pointer) 0x649770 
    .fake = 0
    .fake = 0
}

It seems when calling type bound procedure of ‘b’, the ‘this’ is failed to pass to the procedure. However, the ‘this’ to ‘a’ is sucessfully passed to type bound procedure of ‘a’.

I think I have to avoid to use the type-bound procedure until PGI fixed the bug.

Hi fgao,

Thanks for the example. I have reproduced the error here and sent a report (TPR#18139) to our engineers for further review.

  • Mat

fgao,

Sorry for the late update.

regards,
dave