我正在处理由多个模块组成的大型Fortran代码,并使用OOP功能。使用 gfortran 版本 7 到 9 编译此代码时,我遇到了一个错误。
- 我在下面提供了一个最小的工作示例来重现该错误。它可以保存为
test.f95
并用gfortran -fcheck=all -c test.f95
编译。 - 将
-fcheck=all
传递给编译器时会触发该 bug。 - 该错误出现在 gfortran 7、8 和 9 中,但不出现在以前的版本中(使用 gfortran 5 和 6 进行测试(。请参阅下面的编译器输出。
- 我正在使用 Ubuntu 18.04.3 LTS,4.15.0-65 通用x86_64
有人可以尝试重现并确认此错误吗?我查看了不同的错误跟踪系统,但找不到类似的东西。我还没有
报告,并希望确保在报告之前值得报告。另外,有没有办法解决这个编译器错误?
最小工作示例:
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
一些评论,来自反复试验:
- 在
foo
的定义中,如果m
被指定为固定长度的向量(例如,type(comp) :: m(10)
(,则会触发相同的错误。allocatable
似乎不是这里的罪魁祸首。 - 使用
type(par)
而不是class(par)
在comp
中定义p
不会触发 bug。但是我需要p
在我的代码中是多态的。 - 当
p
被指定为指针而不是可分配的向量时,同样的错误。 fun_par()
中结果y
的维度似乎有问题:例如,当它是标量时(y
而不是y(size(x))
(,错误不会被触发。
编译器错误消息
使用 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.
使用 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.
使用 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.
使用 Gfortran 6.5.0和 Gfortran 5.5.0:无错误。
未知的内部编译器错误总是值得报告的。 在这种情况下,我也找不到报告,但更熟悉海湾合作委员会历史的人可能会找到一份报告。
要解决此编译器错误,似乎可以直接引用函数fun_par
而不是组件p
的绑定fun
:
write(*,*) fun_par(this%m(1)%p, x)
最后,我们可以使示例稍微小一点:
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