- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
the following code produces a segfault in ifort 19.04 but runs fin in gfortran 9.1
Module mod_m1 Type :: parent real, allocatable :: a(:,:) contains private procedure, pass(this) :: copy => subcopy generic, public :: assignment(=) => copy end type parent Type, extends(parent) :: child real, allocatable :: x(:,:) end type child interface parent module procedure new_parent end interface parent interface child module procedure new_child_1 module procedure new_child_2 end interface child contains Subroutine subcopy(ot,this) implicit none Class(parent), intent(in) :: this class(parent), intent(out), allocatable :: ot write(*,*) "copy" allocate(ot,source=this) end Subroutine subcopy Function new_parent(dim) integer, intent(in) :: dim type(parent), allocatable :: new_parent write(*,*) "new_parent" allocate(new_parent) allocate(new_parent%a(dim,dim)) end Function new_parent Function new_child_1() type(child), allocatable :: new_child_1 write(*,*) "new_child_1" allocate(new_child_1) end Function new_child_1 Function new_child_2(dim1,dim2) integer, intent(in) :: dim1, dim2 type(child), allocatable :: new_child_2 write(*,*) "new_child_2" allocate(new_child_2) allocate(new_child_2%a(dim1,dim1)) allocate(new_child_2%x(dim2,dim2)) end Function new_child_2 end Module mod_m1 Program test use mod_m1 implicit none class(parent), allocatable :: a,b write(*,*) "a" allocate(child::a); write(*,*) "b" b=child(5,5) write(*,*) allocated(b) end Program test
it appears as if "allocate(child::a) is not automatically replaced by constructor new_child_1 ......... which is sort of ok. However, "b=child(5,5)" yields a segfault with message:
a b forrtl: severe (408): fort: (7): Attempt to use pointer B when it is not associated with a target Image PC Routine Line Source a.out 000000000040D9E6 Unknown Unknown Unknown a.out 00000000004052D6 Unknown Unknown Unknown a.out 00000000004037E2 Unknown Unknown Unknown libc-2.29.so 000014A882A90EE3 __libc_start_main Unknown Unknown a.out 00000000004036EE Unknown Unknown Unknown
whereas when run with gfortran the output is as expected:
a b new_child_2 copy T
I am wondering whether this is a bug in ifort or gfortran except is wrong code.
Any idea.
Thanks
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I think the code in the original post is non-conformant with respect to the standard given type-bound generic for assignment operation: the standard states an instruction shall not reference an unallocated ALLOCATABLE object whereas the implemented specific procedure for the defined assignment informs the processor to do so. Something along the lines of the modified code shown below is likely what is called for here, though one has to be very careful with defined operations in situations of type extension (inheritance) and polymorphism (see this: https://groups.google.com/d/msg/comp.lang.fortran/EtGmIRqvF2E/ITrDC4iuCAAJ):
module mod_m1 implicit none type :: parent real, allocatable :: a(:,:) contains private end type parent type, extends(parent) :: child real, allocatable :: x(:,:) end type child interface parent module procedure new_parent end interface parent interface assignment(=) module procedure subcopy end interface interface child module procedure new_child_1 module procedure new_child_2 end interface child contains subroutine subcopy(ot,this) class(parent), intent(in) :: this class(parent), intent(out), allocatable :: ot write(*,*) "copy" allocate(ot,source=this) end subroutine subcopy function new_parent(dim) integer, intent(in) :: dim type(parent), allocatable :: new_parent write(*,*) "new_parent" allocate(new_parent) allocate(new_parent%a(dim,dim)) end function new_parent function new_child_1() type(child), allocatable :: new_child_1 write(*,*) "new_child_1" allocate(new_child_1) end function new_child_1 function new_child_2(dim1,dim2) integer, intent(in) :: dim1, dim2 type(child), allocatable :: new_child_2 write(*,*) "new_child_2" allocate(new_child_2) allocate(new_child_2%a(dim1,dim1)) allocate(new_child_2%x(dim2,dim2)) end function new_child_2 end module mod_m1 program test use mod_m1 implicit none class(parent), allocatable :: a,b write(*,*) "a" allocate(child::a); write(*,*) "b" b=child(5,5) write(*,*) allocated(b) end program test
Upon execution using Intel Fortran 19.0 update 5 as well as gfortran:
a b new_child_2 copy T
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks
this implies that
write(*,*) "b" allocate(b) b=child(5,5)
would have done the trick as well. At least ifort accepts it. Would you agree?
Cheers
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page