【问题标题】:gfortran compiler error with dynamic (allocatable) vector动态(可分配)向量的 gfortran 编译器错误
【发布时间】:2019-10-09 20:05:47
【问题描述】:

我正在编写由多个模块组成并使用 OOP 功能的大型 Fortran 代码。使用 gfortran 版本 7 到 9 编译此代码时,我遇到了一个错误。

  • 我在下面提供了一个最小的工作示例来重现该错误。可以保存为test.f95,用gfortran -fcheck=all -c test.f95编译。
  • -fcheck=all 传递给编译器时会触发该错误。
  • 该错误出现在 gfortran 7、8 和 9 中,但不出现在以前的版本中(使用 gfortran 5 和 6 测试)。请参阅下面的编译器输出。
  • 我使用的是 Ubuntu 18.04.3 LTS,4.15.0-65-generic 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 似乎不是这里的罪魁祸首。
  • comp 中使用type(par) 而不是class(par) 定义p 不会触发错误。但我需要 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:没有错误。

【问题讨论】:

  • 错误信息很清楚请提交完整的错误报告,。更重要的是,如果它是一种回归(如果它以前有效)。
  • 谢谢,我刚刚将错误提交给 bugzilla:gcc.gnu.org/bugzilla/show_bug.cgi?id=92050

标签: compiler-errors fortran dynamic-memory-allocation gfortran


【解决方案1】:

未知的内部编译器错误总是值得报告。在这种情况下,我也找不到报告,但更熟悉 gcc 历史的人可能会找到。

要解决这个编译器错误,看来可以直接引用函数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

【讨论】:

    猜你喜欢
    • 2020-08-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-15
    • 2021-07-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多