Reputation: 943
I am working on a large Fortran code made of multiple modules and using OOP features. I am facing a bug when compiling this code with gfortran versions 7 to 9.
test.f95
and compiled with gfortran -fcheck=all -c test.f95
.-fcheck=all
is passed to the compiler.Could someone try to reproduce and confirm this bug? I have looked at the different bug tracking systems but could not find anything similar. I have not reported it yet and would like to make sure it is worth reporting before doing so.
Also, is there a way of getting around this compiler error?
Minimal working example:
module buggy
implicit none
type :: par
contains
procedure, public :: fun => fun_par
end type par
type comp
class(par), allocatable :: p
end type comp
type foo
type(comp), allocatable :: m(:)
contains
procedure, public :: init => init_foo
procedure, public :: update => update_foo
end type foo
contains
function fun_par(this, x) result(y)
implicit none
class(par) :: this
integer, intent(in) :: x(:)
integer :: y(size(x))
end function fun_par
subroutine init_foo(this, n)
implicit none
class(foo) :: this
integer, intent(in) :: n
integer :: k
allocate(this%m(n))
do k = 1, n
allocate(par :: this%m(k)%p)
end do
end subroutine init_foo
subroutine update_foo(this, x)
implicit none
class(foo) :: this
integer, intent(in) :: x(:)
integer :: k
do k = 1, size(this%m)
write(*,*) this%m(k)%p%fun(x)
end do
end subroutine update_foo
end module buggy
A few remarks, from trial and error:
foo
, the same bug is triggered if m
is specified as a fixed-length vector (e.g., type(comp) :: m(10)
). The allocatable
does not seem to be the culprit here.p
in comp
using type(par)
instead of class(par)
does not trigger the bug. But I need p
to be polymorphic in my code.p
is specified to be a pointer instead of an allocatable vector.y
in fun_par()
seems to be problematic: when it is a scalar for example (y
instead of y(size(x))
), the bug is not triggered.Compiler error messages
with gfortran 9.2.1:
$ /usr/bin/gfortran-9 -fcheck=all -c test.f95
test.f95:50:0:
50 | write(*,*) this%m(k)%p%fun(x)
|
internal compiler error: in gfc_conv_procedure_call, at fortran/trans-expr.c:6785
Please submit a full bug report,
with preprocessed source if appropriate.
See <file:///usr/share/doc/gcc-9/README.Bugs> for instructions.
with gfortran 8.3.0:
$ /usr/bin/gfortran-8 -fcheck=all -c test.f95
test.f95:50:0:
write(*,*) this%m(k)%p%fun(x)
internal compiler error: in gfc_conv_procedure_call, at fortran/trans-expr.c:6410
Please submit a full bug report,
with preprocessed source if appropriate.
See <file:///usr/share/doc/gcc-8/README.Bugs> for instructions.
with gfortran 7.4.0:
$ /usr/bin/gfortran-7 -fcheck=all -c test.f95
test.f95:50:0:
write(*,*) this%m(k)%p%fun(x)
internal compiler error: in gfc_conv_procedure_call, at fortran/trans-expr.c:6290
Please submit a full bug report,
with preprocessed source if appropriate.
See <file:///usr/share/doc/gcc-7/README.Bugs> for instructions.
with gfortran 6.5.0 and gfortran 5.5.0: no error.
Upvotes: 0
Views: 299
Reputation: 32366
Unknown internal compiler errors are always worth reporting. In this case I also cannot find a report, but someone more familiar with gcc's history may be able to find one.
To work around this compiler error, it seems that you can directly reference the function fun_par
rather than the binding fun
of the component p
:
write(*,*) fun_par(this%m(1)%p, x)
Finally, we can make the example slightly more minimal:
module buggy
implicit none
type :: par
contains
procedure, public :: fun => fun_par
end type par
type comp
class(par), allocatable :: p
end type comp
type foo
type(comp), allocatable :: m(:)
end type foo
contains
function fun_par(this)
class(par) :: this
integer :: fun_par(1)
fun_par=0
end function fun_par
subroutine update_foo(this)
class(foo) :: this
write(*,*) this%m(1)%p%fun()
end subroutine update_foo
end module buggy
Upvotes: 1