- 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