Type not extended? Using inheritance…

I get the following weird result when compiling a little test program to see if type extension works.


c:\cygwin\home\pkrysl\f>pgfortran u.f90
NOTE: your trial license will expire in 13 days, 9.33 hours.
PGF90-S-0188-Argument number 1 to id: type mismatch (u.f90: 108)
PGF90-S-0188-Argument number 1 to nfens: type mismatch (u.f90: 108)
PGF90-S-0188-Argument number 1 to conn: type mismatch (u.f90: 108)
0 inform, 0 warnings, 3 severes, 0 fatal for test




Here are my modules and the test program:

module kinds_module

integer, parameter :: integer_kind =SELECTED_INT_KIND(9)
real, parameter :: real_kind =SELECTED_REAL_KIND(15)

end module

module gcellset_module
use kinds_module
implicit none

private

public:: gcellset_type, make_gcellset, constructor, nfens, id, conn

type gcellset_type
private
integer (integer_kind) :: id
integer (integer_kind), allocatable :: conn(:,:)
end type gcellset_type

interface constructor
procedure make_gcellset
end interface

contains

subroutine make_gcellset(gcells,conn,id)
type (gcellset_type), intent(out) :: gcells
integer (integer_kind), intent(in) :: conn(:,:)
integer (integer_kind), intent(in), optional :: id
gcells%id=1
allocate(gcells %conn(size(conn,1),size(conn,2)))
gcells%conn=conn
end subroutine

function id(gcells) result(n)
type (gcellset_type), intent(in) :: gcells
integer (integer_kind) :: n
n=gcells%id
end function

function nfens(gcells) result(n)
type (gcellset_type), intent(in) :: gcells
integer (integer_kind) :: n
n= size(gcells%conn,1)
end function


function conn(gcells,range) result(n)
type (gcellset_type), intent(in) :: gcells
integer (integer_kind), intent(in) :: range(:)
integer (integer_kind) :: n(size(range),size(gcells%conn,2))
n=gcells%conn(range,:)
end function

end module

module gcellset_3_manifold_module
use kinds_module
use gcellset_module
implicit none

private

public:: gcellset_3_manifold_type, make_gcellset_3_manifold, constructor, manifdim

type, extends(gcellset_type) :: gcellset_3_manifold_type
end type

interface constructor
procedure make_gcellset_3_manifold
end interface

contains

subroutine make_gcellset_3_manifold(gcells,conn,id)
type (gcellset_3_manifold_type), intent(out) :: gcells
integer (integer_kind), intent(in) :: conn(:,:)
integer (integer_kind), intent(in), optional :: id
call make_gcellset(gcells,conn,id)
end subroutine

function manifdim(gcells) result(n)
type (gcellset_3_manifold_type), intent(in) :: gcells
integer (integer_kind) :: n
n=3
end function


end module

program test

use kinds_module
use gcellset_module
use gcellset_3_manifold_module
implicit none

type (gcellset_3_manifold_type) :: gcells
integer (integer_kind) :: conns(3,2)
data conns /1, 2,2,3,3,4/
integer (integer_kind) :: range(1)
data range /2/

call make_gcellset_3_manifold(gcells,conns,1)

print *,‘Here id=’,id(gcells),’ nfens=’,nfens(gcells),’ conn=’,conn(gcells,range)

end program test


I would have thought that the function nfens should be fine with the actual argument being gcellset_3_manifold_type since it extends gcellset_type!? Am I doing something wrong?

Thank you for your help,

Petr Krysl

Hi Petr,

Thank you for the example. It looks like the compiler is getting confused between the parent and extended type. I have submitted a technical problem report (TPR#17241) and have passed it to our engineers for further investigation.

Best Regards,
Mat

Hi Petr,

Upon further review, this is not a compiler bug. You need to use class (gcellset_type) instead of type (gcellset_type) for dummy argument gcells in the following routines:

subroutine make_gcellset(gcells,conn,id)
function id(gcells) result(n)
function nfens(gcells) result(n)
function conn(gcells,range) result(n)

gcells is declared with a type extension of gcellset_type called gcellset_3_manifold_type, therefore in order to pass it into a function that takes a gcellset_type, the dummy argument must be polymorphic (i.e., declared with the class keyword, not the type keyword).

However, after fixing these problems, the code did expose a couple other problems with our compiler unrelated to the type mismatch. One problem has to do with private/public statements not appearing to be processed correctly and we’re not properly passing in type descriptors to the class arguments in this case. We have added TPR#17246 to address these issues and will close TPR#17241.

Thanks,
Mat