Description
I'm aware the polymorphic support is still experimental but I think it is useful to have this recorded.
Consider the two following files:
! mymod.f90
module mymod
implicit none
type, abstract :: myfoo
integer :: x
end type myfoo
end module mymod
! mymod2.f90
module mymod2
use mymod, only: myfoo
implicit none
contains
subroutine mysub(myparam)
implicit none
class(myfoo), pointer :: myparam
nullify(myparam)
end subroutine mysub
end module mymod2
If we compile them separatedly, mymod2.f90
will crash while generating FIR because the type descriptor of myfoo
has not been emitted and nullify
needs it.
$ flang-new -flang-experimental-polymorphism -c mymod.f90
$ flang-new -flang-experimental-polymorphism -c mymod2.f90
error: loc("/home/rferrer/fio/upstream/llvm-install/tmp/mymod2.f90":11:7): no type descriptor found for NULLIFY
LLVM ERROR: aborting
I looked into it a bit and IIUC, it seems that the type descriptor is emitted as part of lowerModuleDeclScope
in the Bridge. If the two files together are compiled as a single file (e.g. adding an include 'mymod.f90'
at the beginning of mymod2.f90
) then the crash does not happen because the descriptor is indeed emitted.
In a separate compilation setting, AFAICT the module is loaded and parsed and its names resolved but I don't think we synthesise enough information so the type descriptors get emitted as a consequence of a use
-statement. One thing I saw is that the descriptors (and other runtime info) are already emitted as weak global objects so emitting repeated definitions in different object files should not be a problem.
Any hints on how we could address this? I wonder if it makes sense to check use-associations to derived types and emit their descriptors if they haven't been emitted yet?