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

--- Comment #2 from Jürgen Reuter <juergen.reuter at desy dot de> ---
This is a shorter reproducer:

     1  module iso_varying_string
     2    implicit none
     3    integer, parameter, private :: GET_BUFFER_LEN = 1
     4  
     5    type, public :: varying_string
     6       private
     7       character(LEN=1), dimension(:), allocatable :: chars
     8    end type varying_string
     9  
    10    interface assignment(=)
    11       module procedure op_assign_CH_VS
    12       module procedure op_assign_VS_CH
    13    end interface assignment(=)
    14  
    15    interface char
    16       module procedure char_auto
    17       module procedure char_fixed
    18    end interface char
    19  
    20    interface len
    21       module procedure len_
    22    end interface len
    23  
    24    interface var_str
    25       module procedure var_str_
    26    end interface var_str
    27  
    28    public :: assignment(=)
    29    public :: char
    30    public :: len
    31    public :: var_str
    32  
    33    private :: op_assign_CH_VS
    34    private :: op_assign_VS_CH
    35    private :: char_auto
    36    private :: char_fixed
    37    private :: len_
    38    private :: var_str_
    39  
    40  contains
    41  
    42    elemental function len_ (string) result (length)
    43      type(varying_string), intent(in) :: string
    44      integer                          :: length
    45      if(ALLOCATED(string%chars)) then
    46         length = SIZE(string%chars)
    47      else
    48         length = 0
    49      endif
    50    end function len_
    51  
    52    elemental subroutine op_assign_CH_VS (var, exp)
    53      character(LEN=*), intent(out)    :: var
    54      type(varying_string), intent(in) :: exp
    55      var = char(exp)
    56    end subroutine op_assign_CH_VS
    57  
    58    elemental subroutine op_assign_VS_CH (var, exp)
    59      type(varying_string), intent(out) :: var
    60      character(LEN=*), intent(in)      :: exp
    61      var = var_str(exp)
    62    end subroutine op_assign_VS_CH
    63  
    64    pure function char_auto (string) result (char_string)
    65      type(varying_string), intent(in) :: string
    66      character(LEN=len(string))       :: char_string
    67      integer                          :: i_char
    68      forall(i_char = 1:len(string))
    69         char_string(i_char:i_char) = string%chars(i_char)
    70      end forall
    71    end function char_auto
    72  
    73    pure function char_fixed (string, length) result (char_string)
    74      type(varying_string), intent(in) :: string
    75      integer, intent(in)              :: length
    76      character(LEN=length)            :: char_string
    77      char_string = char(string)
    78    end function char_fixed
    79  
    80    elemental function var_str_ (char) result (string)
    81      character(LEN=*), intent(in) :: char
    82      type(varying_string)         :: string
    83      integer                      :: length
    84      integer                      :: i_char
    85      length = LEN(char)
    86      ALLOCATE(string%chars(length))
    87      forall(i_char = 1:length)
    88         string%chars(i_char) = char(i_char:i_char)
    89      end forall
    90    end function var_str_
    91  
    92  end module iso_varying_string
    93  
    94  module model_data
    95    use, intrinsic :: iso_c_binding !NODEP!
    96    use iso_varying_string, string_t => varying_string
    97  
    98    implicit none
    99    private
   100  
   101    public :: field_data_t
   102    public :: model_data_t
   103  
   104    type :: field_data_t
   105       private
   106       type(string_t) :: longname
   107       integer :: pdg = 0
   108       logical :: has_anti = .false.
   109       type(string_t), dimension(:), allocatable :: name, anti
   110       type(string_t) :: tex_name
   111       integer :: multiplicity = 1
   112     contains
   113       procedure :: init => field_data_init
   114       procedure :: set => field_data_set
   115       procedure :: get_longname => field_data_get_longname
   116       procedure :: get_name_array => field_data_get_name_array
   117    end type field_data_t
   118  
   119    type :: model_data_t
   120       private
   121       type(field_data_t), dimension(:), allocatable :: field
   122     contains
   123       generic :: init => model_data_init
   124       procedure, private :: model_data_init
   125       procedure :: get_field_array_ptr => model_data_get_field_array_ptr
   126       procedure :: get_field_ptr_by_index =>
model_data_get_field_ptr_index
   127       procedure :: init_sm_test => model_data_init_sm_test
   128    end type model_data_t
   129  
   130  
   131  contains
   132  
   133    subroutine field_data_init (prt, longname, pdg)
   134      class(field_data_t), intent(out) :: prt
   135      type(string_t), intent(in) :: longname
   136      integer, intent(in) :: pdg
   137      prt%longname = longname
   138      prt%pdg = pdg
   139      prt%tex_name = ""
   140    end subroutine field_data_init
   141  
   142    subroutine field_data_set (prt, &
   143         name, anti, tex_name)
   144      class(field_data_t), intent(inout) :: prt
   145      type(string_t), dimension(:), intent(in), optional :: name, anti
   146      type(string_t), intent(in), optional :: tex_name
   147      if (present (name)) then
   148         if (allocated (prt%name))  deallocate (prt%name)
   149         allocate (prt%name (size (name)), source = name)
   150      end if
   151      if (present (anti)) then
   152         if (allocated (prt%anti))  deallocate (prt%anti)
   153         allocate (prt%anti (size (anti)), source = anti)
   154         prt%has_anti = .true.
   155      end if
   156      if (present (tex_name))  prt%tex_name = tex_name
   157    end subroutine field_data_set
   158  
   159    pure function field_data_get_longname (prt) result (name)
   160      type(string_t) :: name
   161      class(field_data_t), intent(in) :: prt
   162      name = prt%longname
   163    end function field_data_get_longname
   164  
   165    subroutine field_data_get_name_array (prt, is_antiparticle, name)
   166      class(field_data_t), intent(in) :: prt
   167      logical, intent(in) :: is_antiparticle
   168      type(string_t), dimension(:), allocatable, intent(inout) :: name
   169      if (allocated (name))  deallocate (name)
   170      if (is_antiparticle) then
   171         if (prt%has_anti) then
   172            allocate (name (size (prt%anti)))
   173            name = prt%anti
   174         else
   175            allocate (name (0))
   176         end if
   177      else
   178         allocate (name (size (prt%name)))
   179         name = prt%name
   180      end if
   181    end subroutine field_data_get_name_array
   182  
   183    subroutine model_data_init (model, n_field)
   184      class(model_data_t), intent(out) :: model
   185      integer, intent(in) :: n_field
   186      allocate (model%field (n_field))
   187    end subroutine model_data_init
   188  
   189    function model_data_get_field_array_ptr (model) result (ptr)
   190      class(model_data_t), intent(in), target :: model
   191      type(field_data_t), dimension(:), pointer :: ptr
   192      ptr => model%field
   193    end function model_data_get_field_array_ptr
   194  
   195    function model_data_get_field_ptr_index (model, i) result (ptr)
   196      class(model_data_t), intent(in), target :: model
   197      integer, intent(in) :: i
   198      type(field_data_t), pointer :: ptr
   199      ptr => model%field(i)
   200    end function model_data_get_field_ptr_index
   201  
   202    subroutine model_data_init_sm_test (model)
   203      class(model_data_t), intent(out) :: model
   204      type(field_data_t), pointer :: field
   205      integer :: i
   206      call model%init (2)
   207      i = 0
   208      i = i + 1
   209      field => model%get_field_ptr_by_index (i)
   210      call field%init (var_str ("W_BOSON"), 24)
   211      call field%set (name = [var_str ("W+")], anti = [var_str ("W-")])
   212      i = i + 1
   213      field => model%get_field_ptr_by_index (i)
   214      call field%init (var_str ("HIGGS"), 25)
   215      call field%set (name = [var_str ("H")])
   216    end subroutine model_data_init_sm_test
   217    
   218  end module model_data
   219  
   220  
   221  module models
   222    use, intrinsic :: iso_c_binding !NODEP!
   223    use iso_varying_string, string_t => varying_string
   224    use model_data
   225    use parser
   226    use variables
   227    implicit none
   228    private
   229    public :: model_t
   230  
   231    type, extends (model_data_t) :: model_t
   232       private
   233     contains
   234       procedure :: append_field_vars => model_append_field_vars
   235    end type model_t
   236  
   237  contains
   238  
   239    subroutine model_append_field_vars (model)
   240      class(model_t), intent(inout) :: model
   241      type(field_data_t), dimension(:), pointer :: field_array
   242      type(field_data_t), pointer :: field
   243      type(string_t) :: name
   244      type(string_t), dimension(:), allocatable :: name_array
   245      integer :: i, j
   246      field_array => model%get_field_array_ptr ()
   247      do i = 1, size (field_array)
   248         name = field_array(i)%get_longname ()
   249         call field_array(i)%get_name_array (.false., name_array)
   250      end do
   251    end subroutine model_append_field_vars
   252    
   253  end module models
   254  
   255  
   256  program main_ut
   257    use iso_varying_string, string_t => varying_string
   258    use model_data
   259    use models
   260    implicit none
   261  
   262    class(model_data_t), pointer :: model
   263    model => null ()
   264    allocate (model_t :: model)
   265    select type (model)
   266    type is (model_t)
   267       call model%init_sm_test ()
   268       call model%append_field_vars ()
   269    end select
   270  end program main_ut

Reply via email to