! { dg-do compile } ! { dg-options "-fdump-tree-original" } ! ! Test the fix for PR117763, which was a regression caused by the patch for ! PR109345. ! ! Contributed by Juergen Reuter ! 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 ! use parser ! use variables 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 ! { dg-final { scan-tree-dump-times "__result->span = \[12\].." 1 "original" } }