Ошибка компилятора gfortran с динамическим (выделяемым) вектором - PullRequest
0 голосов
/ 09 октября 2019

Я работаю над большим кодом на Фортране, состоящим из нескольких модулей и использующим функции ООП. Я сталкиваюсь с ошибкой при компиляции этого кода с версиями 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 здесь не является виновником.
  • Определение p в comp с использованием type(par) вместо class(par) не вызывает ошибку. Но мне нужно, чтобы p был полиморфным в моем коде.
  • Та же ошибка, когда p указан как указатель вместо выделяемого вектора.
  • Размерность результата y в fun_par() кажется проблематичным: например, когда речь идет о скаляре (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: без ошибок.

1 Ответ

1 голос
/ 10 октября 2019

Неизвестные внутренние ошибки компилятора всегда стоит сообщить. В этом случае я также не могу найти отчет, но кто-то, более знакомый с историей gcc, может найти его.

Чтобы обойти эту ошибку компилятора, кажется, что вы можете напрямую ссылаться на функцию fun_parчем связывание fun компонента p:

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...