带有动态(可分配)向量的 gfortran 编译器错误



我正在处理由多个模块组成的大型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

最新更新