in the example program below I experienced a problem with the MOVE_ALLOC intrinsic, where the 'TO' argument is polymorphic, but the 'FROM' is not.
I am aware that there have been recent compiler issues with MOVE_ALLOC, nevertheless I would be happy to get some helpful advice again whether it's the compiler or me who is wrong in this case.
module m ! a derived type type other_type integer :: i = 5 end type ! container, has allocatable component of derived type type:: container_type CLASS(other_type), allocatable :: alloc_comp ! (*) end type end module program p use m implicit none type(container_type) :: original type(container_type), allocatable :: copy TYPE(other_type), allocatable :: alloc_var ! (**) ! initialize alloc. comp. in 'original' container allocate(alloc_var) call move_alloc(alloc_var,original%alloc_comp) ! copy the container allocate(copy, source=original) ! check if ultimate allocatable components have been copied, too print *, allocated(copy%alloc_comp) ! answer: T ! read ultimate alloc. components from copy print *, copy%alloc_comp%i ! CRASH (access violation) end program
The list below shows the compilation status for variuous combination of polymoprhic/non-polymoprhic FROM and TO arguments in MOVE_ALLOC.
line (*) line (**) compilation? [TO] [FROM] class class OK type type OK class type CRASH: access violation, as described in example code type class CRASH: compiler seg. violation (but illegal fortran code)
While the last configuration is illegal (polymorphic 'FROM' needs polymorphic 'TO'), I think the previous should be legal (if not, I whish the compiler could raise an error, because the source of that error was hard to find in my original code).
- After executing MOVE_ALLOC, the polymorphic 'TO' component seems to be allocated with the correct dynamic type of 'FROM' and can also be read (within an additional select type).
- However, the so initialized component of the container is not correctly copied via ALLOCATE from the SOURCE expression.
While the allocation status in the copy is 'allocated', accessing the component causes a segmentation fault.
- The use of ALLOCATE(original%alloc_comp, SOURCE=alloc_var) instead of MOVE_ALLOC for the initialization fixes the problems.
Best regards and thanks for your answers,