move_alloc from polymorphic causes segfault

move_alloc from polymorphic causes segfault

Hello again,

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

Remarks:

  • 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,

Ferdinand

5 帖子 / 0 全新
最新文章
如需更全面地了解编译器优化,请参阅优化注意事项

While doing more research on this, I found an old thread concerning the same issue in ifort 12 here:

http://software.intel.com/en-us/forums/topic/281144

Is this issue still present in version 13.x?

Nevertheless, the proposed workaround there ('make both arguments polymorphic') doesn't help me in my original code (/= the example), where the 'TO' argument is an abstract class. Declaring both arguments as 'class', they still cause the segmentation fault after beeing copied via ALLOCATE (nevertheless both polymorphic). Maybe I can post more details from my original code, if those can be helpful in fixing this problem.

Steve Lionel (Intel)的头像

The internal compiler error is already fixed for a release later this year.

The problem from the thread you linked is not present in 13.x. Yours is a new issue that I have escalated as DPD200241859. I will let you know of any progress. What I see is that the ALLOCATED call is returning incorrect information - my guess is that the MOVE_ALLOC, where the destination is polymorphic but the source is not, is not properly filling in the destination's descriptor.

Steve

Thanks for the clarification. The ALLOCATED call indeed returns TRUE, but I think this is more or less correct in the way that the ultimate allocatable component should be allocated after creating a copy with ALLOCATE*. The problem is that, in fact, it is not. I also got the impression that the MOVE_ALLOC messed it up.

Regards, Ferdinand

*) This is what I concluded from the Intel® Fortran Compiler XE 13.1 reference pages - which I find very helpful and well written also for less experienced users (while the standard or other manuals are a lot harder to read without prior knowledge of all the finer fortran details). Just had to mention that ;-).

http://software.intel.com/sites/products/documentation/doclib/stdxe/2013... (second paragraph from the end)

Steve Lionel (Intel)的头像

The newer issue is now also fixed for a release later this year.

Steve

登陆并发表评论。