I have the following simple example program:
module abstract_writer
implicit none
private
public :: writer_type
type, abstract :: writer_type
contains
procedure(write_integer_interface), deferred :: write_integer
generic :: write => write_integer
end type
abstract interface
subroutine write_integer_interface(writer, v)
import writer_type
class(writer_type),intent(inout) :: writer
integer, intent(in) :: v(:)
end subroutine
end interface
end module abstract_writer
And some concrete writers:
module screen_writer_mod
use abstract_writer, only: writer_type
implicit none
type, extends(writer_type) :: screen_writer_type
contains
procedure :: write_integer => write_integer_to_screen
end type
contains
subroutine write_integer_to_screen(writer, v)
class(screen_writer_type), intent(inout) :: writer
integer, intent(in) :: v(:)
print *, 'integer', v
end subroutine
end module
and a pointer list one
module writer_pointer_mod
use abstract_writer, only: writer_type
implicit none
private
public :: pointer_writer_type, append_writer
type writer_ptr
class(writer_type), pointer :: ptr => null()
end type
type, extends(writer_type) :: pointer_writer_type
type(writer_ptr), allocatable :: writer_list(:)
contains
procedure :: write_integer => write_integer_from_list
end type
contains
subroutine append_writer(writer_cont, writer)
type(pointer_writer_type), intent(inout) :: writer_cont
class(writer_type), pointer, intent(in) :: writer
if (.not. allocated(writer_cont%writer_list)) allocate(writer_cont%writer_list(0))
writer_cont%writer_list = [writer_cont%writer_list, writer_ptr(writer)]
end subroutine
subroutine write_integer_from_list(writer, v)
class(pointer_writer_type), intent(inout) :: writer
integer, intent(in) :: v(:)
integer:: n, i
if (.not. allocated(writer%writer_list)) return
n = size(writer%writer_list)
do i=1,n
if (.not.associated(writer%writer_list(i)%ptr)) cycle
call writer%writer_list(i)%ptr%write(v)
end do
end subroutine
end module
Where I’m storing pointer to the writers in an array.
And of course the main
module writer_user
use abstract_writer, only: writer_type
implicit none
contains
subroutine use_writer(writer)
class(writer_type) :: writer
integer,allocatable :: x(:)
x = [1,2,3,4,5,6,7,8,9,10]
call writer%write(x)
end subroutine
end module
program main
use screen_writer_mod, only: screen_writer_type
use writer_pointer_mod, only: pointer_writer_type, append_writer
use writer_user, only: use_writer
implicit none
type(screen_writer_type), target :: swriter
type(pointer_writer_type) :: pwriter
print *,'Appending new writers'
call append_writer(pwriter, swriter)
call use_writer(pwriter)
end program main
Now.
gfortran 13.2 accept and runs it:
[g2egiova@viz06 abstract_write_lf_bug]$ fpm run --compiler gfortran
abstract_writer.f90 done.
writer_pointer_mod.f90 done.
writer_user.f90 done.
screen_writer.f90 done.
libabstract_writer.a done.
main.f90 done.
abstract_writer done.
[100%] Project compiled successfully.
Appending new writers
integer 1 2 3 4 5 6 7 8 9 10
ifx (IFX) 2023.2.0 20230721 rejects it
[g2egiova@viz06 abstract_write_lf_bug]$ fpm run --compiler ifx
abstract_writer.f90 done.
writer_pointer_mod.f90 done.
writer_user.f90 done.
screen_writer.f90 done.
libabstract_writer.a done.
main.f90 failed.
[ 85%] Compiling...
app/main.f90(12): error #6633: The type of the actual argument differs from the type of the dummy argument. [SWRITER]
call append_writer(pwriter, swriter)
------------------------------^
compilation aborted for app/main.f90 (code 1)
<ERROR> Compilation failed for object " app_main.f90.o "
<ERROR> stopping due to failed compilation
STOP 1
lfortran (LFortran version: 0.67.0-35-g44a399676) compiles it but fail to execute
[g2egiova@viz06 abstract_write_lf_bug]$ fpm run --compiler lfortran --flag --realloc-lhs-arrays
abstract_writer.f90 done.
writer_pointer_mod.f90 done.
writer_user.f90 done.
screen_writer.f90 done.
libabstract_writer.a done.
main.f90 done.
abstract_writer done.
[100%] Project compiled successfully.
Appending new writers
free(): double free detected in tcache 2
<ERROR> Execution for object " abstract_writer " returned exit code 134
<ERROR> *cmd_run*:stopping due to failed executions
STOP 134
Is the program correct, is it a bug in that, not very new, version of ifx, there could be a way to make it work with lfortran?