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