Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

Assignment with polymorphic members

Jacob_Williams
New Contributor III
1,002 Views

I'm wondering if the following is a compiler bug or I'm doing something non-standard.  If I have a variable that is a type that contains polymorphic types, can I use an "=" assignment statement to set one equal to the other?  It works for scalars, but not for vectors.  If the vector is non-allocatable, then the assignment triggers an access violation.  If the vector is allocatable, then the assignment deallocates the vector.  If the type does not contain a polymorphic entity, then everything works fine.  See example below.

[fortran]

!*******************************************************************************************************
    module test_module
!*******************************************************************************************************
    
    implicit none
    
    private
    
    type,public :: atype
        integer :: i = 1
    end type atype
    type,extends(atype),public :: ctype
        integer :: k = 3
    end type ctype
    
    type,public :: my_type
        integer,dimension(:),allocatable    :: ivec
        class(atype),allocatable            :: abc
    end type my_type
    
    public :: test_routine_1,test_routine_2,test_routine_3
    
    contains
!*******************************************************************************************************

!******************************************************************    
    subroutine test_routine_1()
!******************************************************************    
    implicit none
    
    type(my_type) :: r1,r2
        
    !---scalar version:
    
    allocate(r1%ivec(2))
    allocate( ctype :: r1%abc )
        
    r2 = r1        !This works
    
    write(*,*) ''
    write(*,*) ' scalar version '
    write(*,*) 'allocated(r2%ivec)    ', allocated(r2%ivec)            !T
    write(*,*) 'allocated(r2%abc)     ', allocated(r2%abc)            !T

!******************************************************************    
    end subroutine test_routine_1    
!******************************************************************    
    
!******************************************************************    
    subroutine test_routine_2()
!******************************************************************    
    implicit none
    
    type(my_type),dimension(2) :: seg
        
    !---vector version (nonallocatable):

    allocate(seg(1)%ivec(2))
    allocate( ctype :: seg(1)%abc )
    
    write(*,*) ''
    write(*,*) ' vector version (nonallocatable) '
    write(*,*) 'allocated(seg(1)%ivec) ', allocated(seg(1)%ivec)    !T
    write(*,*) 'allocated(seg(2)%ivec) ', allocated(seg(2)%ivec)    !F
    
    seg(2) = seg(1)                                                !crash due to access violation!!!
        
    write(*,*) ''
    write(*,*) 'allocated(seg(1)%ivec) ', allocated(seg(1)%ivec)
    write(*,*) 'allocated(seg(2)%ivec) ', allocated(seg(2)%ivec)

!******************************************************************    
    end subroutine test_routine_2        
!******************************************************************    
    
!******************************************************************    
    subroutine test_routine_3()
!******************************************************************    
    implicit none
    
    type(my_type),dimension(:),allocatable :: seg
        
    !---vector version (allocatable):

    allocate(seg(2))

    allocate(seg(1)%ivec(2))
    allocate( ctype :: seg(1)%abc )
    
    write(*,*) ''
    write(*,*) ' vector version (allocatable) '
    write(*,*) 'allocated(seg)         ', allocated(seg)            !T
    write(*,*) 'allocated(seg(1)%ivec) ', allocated(seg(1)%ivec)    !T
    write(*,*) 'allocated(seg(2)%ivec) ', allocated(seg(2)%ivec)    !F
    
    seg(2) = seg(1)                                                    !This is deallocating the seg array!!!
        
    write(*,*) ''
    write(*,*) 'allocated(seg)         ', allocated(seg)            !F
    write(*,*) 'allocated(seg(1)%ivec) ', allocated(seg(1)%ivec)    !crash due to access violation!!!
    write(*,*) 'allocated(seg(2)%ivec) ', allocated(seg(2)%ivec)

!******************************************************************    
    end subroutine test_routine_3    
!******************************************************************    
    
!*******************************************************************************************************
    end module test_module
!*******************************************************************************************************
    
!*******************************************************************************************************
    program main
!*******************************************************************************************************
    use test_module
    
    call test_routine_1()    !OK
    call test_routine_2()    !crash
    call test_routine_3()    !crash
    
!*******************************************************************************************************
    end program main
!*******************************************************************************************************

[/fortran]

0 Kudos
8 Replies
Steven_L_Intel1
Employee
1,002 Views

I don't see any errors with this code. It builds and runs ok for me in 14.0. You don't even need /standard-semantics here.


  scalar version
 allocated(r2%ivec)     T
 allocated(r2%abc)      T

  vector version (nonallocatable)
 allocated(seg(1)%ivec)  T
 allocated(seg(2)%ivec)  F

 allocated(seg(1)%ivec)  T
 allocated(seg(2)%ivec)  T

  vector version (allocatable)
 allocated(seg)          T
 allocated(seg(1)%ivec)  T
 allocated(seg(2)%ivec)  F

 allocated(seg)          T
 allocated(seg(1)%ivec)  T
 allocated(seg(2)%ivec)  T

0 Kudos
Jacob_Williams
New Contributor III
1,001 Views

Interesting... Here is a zipped version of my project.  I get access violations for both the Debug and Release builds.  I'm using a Windows 7 64 bit machine, using Visual Studio 2010 and the 32 bit version of the 14.0 Intel compiler.

0 Kudos
Steven_L_Intel1
Employee
1,002 Views

I'm actually using a pre-release version of Update 1, so it's possible we fixed a problem between the initlal 14.0 and the update. I can't test the older version right away, so I suggest just waiting for Update 1 (shouldn't be more than a few days.)

0 Kudos
Jacob_Williams
New Contributor III
1,002 Views

No problem!  I can wait.  So, the code is standard-conforming? (The polymorphic element should be automatically allocated to the correct type when using "=")?

0 Kudos
IanH
Honored Contributor III
1,002 Views

Your understanding of what should happen is correct, and the code looks ok to me from a cursory examination.  I've been informed previously (it might have been by Steve on this forum or perhaps it was via premier support) that there are fixes in the October update that would address issues with similar characteristics to what you've encountered.

0 Kudos
Steven_L_Intel1
Employee
1,002 Views

I saw nothing wrong with the code. Amd I just now tried it with the September release and it indeed fails.

0 Kudos
Jacob_Williams
New Contributor III
1,002 Views

The bug is indeed fixed in v2013 SP1 Update 1.

0 Kudos
Steven_L_Intel1
Employee
1,001 Views

Glad to hear it.

0 Kudos
Reply