https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117763

--- Comment #3 from Jürgen Reuter <juergen.reuter at desy dot de> ---
Comment on attachment 59688
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=59688
Shorter reproducer

>module iso_varying_string
>  implicit none
>  integer, parameter, private :: GET_BUFFER_LEN = 1
>
>  type, public :: varying_string
>     private
>     character(LEN=1), dimension(:), allocatable :: chars
>  end type varying_string
>
>  interface assignment(=)
>     module procedure op_assign_CH_VS
>     module procedure op_assign_VS_CH
>  end interface assignment(=)
>
>  interface char
>     module procedure char_auto
>     module procedure char_fixed
>  end interface char
>
>  interface len
>     module procedure len_
>  end interface len
>
>  interface var_str
>     module procedure var_str_
>  end interface var_str
>
>  public :: assignment(=)
>  public :: char
>  public :: len
>  public :: var_str
>
>  private :: op_assign_CH_VS
>  private :: op_assign_VS_CH
>  private :: char_auto
>  private :: char_fixed
>  private :: len_
>  private :: var_str_
>
>contains
>
>  elemental function len_ (string) result (length)
>    type(varying_string), intent(in) :: string
>    integer                          :: length
>    if(ALLOCATED(string%chars)) then
>       length = SIZE(string%chars)
>    else
>       length = 0
>    endif
>  end function len_
>
>  elemental subroutine op_assign_CH_VS (var, exp)
>    character(LEN=*), intent(out)    :: var
>    type(varying_string), intent(in) :: exp
>    var = char(exp)
>  end subroutine op_assign_CH_VS
>
>  elemental subroutine op_assign_VS_CH (var, exp)
>    type(varying_string), intent(out) :: var
>    character(LEN=*), intent(in)      :: exp
>    var = var_str(exp)
>  end subroutine op_assign_VS_CH
>
>  pure function char_auto (string) result (char_string)
>    type(varying_string), intent(in) :: string
>    character(LEN=len(string))       :: char_string
>    integer                          :: i_char
>    forall(i_char = 1:len(string))
>       char_string(i_char:i_char) = string%chars(i_char)
>    end forall
>  end function char_auto
>
>  pure function char_fixed (string, length) result (char_string)
>    type(varying_string), intent(in) :: string
>    integer, intent(in)              :: length
>    character(LEN=length)            :: char_string
>    char_string = char(string)
>  end function char_fixed
>
>  elemental function var_str_ (char) result (string)
>    character(LEN=*), intent(in) :: char
>    type(varying_string)         :: string
>    integer                      :: length
>    integer                      :: i_char
>    length = LEN(char)
>    ALLOCATE(string%chars(length))
>    forall(i_char = 1:length)
>       string%chars(i_char) = char(i_char:i_char)
>    end forall
>  end function var_str_
>
>end module iso_varying_string
>
>module model_data
>  use, intrinsic :: iso_c_binding !NODEP!
>  use iso_varying_string, string_t => varying_string
>
>  implicit none
>  private
>
>  public :: field_data_t
>  public :: model_data_t
>
>  type :: field_data_t
>     private
>     type(string_t) :: longname
>     integer :: pdg = 0
>     logical :: has_anti = .false.
>     type(string_t), dimension(:), allocatable :: name, anti
>     type(string_t) :: tex_name
>     integer :: multiplicity = 1
>   contains
>     procedure :: init => field_data_init
>     procedure :: set => field_data_set
>     procedure :: get_longname => field_data_get_longname
>     procedure :: get_name_array => field_data_get_name_array
>  end type field_data_t
>
>  type :: model_data_t
>     private
>     type(field_data_t), dimension(:), allocatable :: field
>   contains
>     generic :: init => model_data_init
>     procedure, private :: model_data_init
>     procedure :: get_field_array_ptr => model_data_get_field_array_ptr
>     procedure :: get_field_ptr_by_index => model_data_get_field_ptr_index
>     procedure :: init_sm_test => model_data_init_sm_test
>  end type model_data_t
>
>
>contains
>
>  subroutine field_data_init (prt, longname, pdg)
>    class(field_data_t), intent(out) :: prt
>    type(string_t), intent(in) :: longname
>    integer, intent(in) :: pdg
>    prt%longname = longname
>    prt%pdg = pdg
>    prt%tex_name = ""
>  end subroutine field_data_init
>
>  subroutine field_data_set (prt, &
>       name, anti, tex_name)
>    class(field_data_t), intent(inout) :: prt
>    type(string_t), dimension(:), intent(in), optional :: name, anti
>    type(string_t), intent(in), optional :: tex_name
>    if (present (name)) then
>       if (allocated (prt%name))  deallocate (prt%name)
>       allocate (prt%name (size (name)), source = name)
>    end if
>    if (present (anti)) then
>       if (allocated (prt%anti))  deallocate (prt%anti)
>       allocate (prt%anti (size (anti)), source = anti)
>       prt%has_anti = .true.
>    end if
>    if (present (tex_name))  prt%tex_name = tex_name
>  end subroutine field_data_set
>
>  pure function field_data_get_longname (prt) result (name)
>    type(string_t) :: name
>    class(field_data_t), intent(in) :: prt
>    name = prt%longname
>  end function field_data_get_longname
>
>  subroutine field_data_get_name_array (prt, is_antiparticle, name)
>    class(field_data_t), intent(in) :: prt
>    logical, intent(in) :: is_antiparticle
>    type(string_t), dimension(:), allocatable, intent(inout) :: name
>    if (allocated (name))  deallocate (name)
>    if (is_antiparticle) then
>       if (prt%has_anti) then
>          allocate (name (size (prt%anti)))
>          name = prt%anti
>       else
>          allocate (name (0))
>       end if
>    else
>       allocate (name (size (prt%name)))
>       name = prt%name
>    end if
>  end subroutine field_data_get_name_array
>
>  subroutine model_data_init (model, n_field)
>    class(model_data_t), intent(out) :: model
>    integer, intent(in) :: n_field
>    allocate (model%field (n_field))
>  end subroutine model_data_init
>
>  function model_data_get_field_array_ptr (model) result (ptr)
>    class(model_data_t), intent(in), target :: model
>    type(field_data_t), dimension(:), pointer :: ptr
>    ptr => model%field
>  end function model_data_get_field_array_ptr
>
>  function model_data_get_field_ptr_index (model, i) result (ptr)
>    class(model_data_t), intent(in), target :: model
>    integer, intent(in) :: i
>    type(field_data_t), pointer :: ptr
>    ptr => model%field(i)
>  end function model_data_get_field_ptr_index
>
>  subroutine model_data_init_sm_test (model)
>    class(model_data_t), intent(out) :: model
>    type(field_data_t), pointer :: field
>    integer :: i
>    call model%init (2)
>    i = 0
>    i = i + 1
>    field => model%get_field_ptr_by_index (i)
>    call field%init (var_str ("W_BOSON"), 24)
>    call field%set (name = [var_str ("W+")], anti = [var_str ("W-")])
>    i = i + 1
>    field => model%get_field_ptr_by_index (i)
>    call field%init (var_str ("HIGGS"), 25)
>    call field%set (name = [var_str ("H")])
>  end subroutine model_data_init_sm_test
>  
>end module model_data
>
>
>module models
>  use, intrinsic :: iso_c_binding !NODEP!
>  use iso_varying_string, string_t => varying_string
>  use model_data
>  implicit none
>  private
>  public :: model_t
>
>  type, extends (model_data_t) :: model_t
>     private
>   contains
>     procedure :: append_field_vars => model_append_field_vars
>  end type model_t
>
>contains
>
>  subroutine model_append_field_vars (model)
>    class(model_t), intent(inout) :: model
>    type(field_data_t), dimension(:), pointer :: field_array
>    type(field_data_t), pointer :: field
>    type(string_t) :: name
>    type(string_t), dimension(:), allocatable :: name_array
>    integer :: i, j
>    field_array => model%get_field_array_ptr ()
>    do i = 1, size (field_array)
>       name = field_array(i)%get_longname ()
>       call field_array(i)%get_name_array (.false., name_array)
>    end do
>  end subroutine model_append_field_vars
>  
>end module models
>
>
>program main_ut
>  use iso_varying_string, string_t => varying_string
>  use model_data
>  use models
>  implicit none
>
>  class(model_data_t), pointer :: model
>  model => null ()
>  allocate (model_t :: model)
>  select type (model)
>  type is (model_t)
>     call model%init_sm_test ()
>     call model%append_field_vars ()
>  end select
>end program main_ut

Reply via email to