! { dg-do run } ! ! Check error of pr65894 are fixed. ! Contributed by Juergen Reuter ! Andre Vehreschild module simple_string ! Minimal iso_varying_string implementation needed. implicit none type string_t private character(len=1), dimension(:), allocatable :: cs end type string_t contains elemental function var_str(c) result (s) character(*), intent(in) :: c type(string_t) :: s integer :: l,i l = len(c) allocate(s%cs(l)) forall(i = 1:l) s%cs(i) = c(i:i) end forall end function var_str end module simple_string module model_data use simple_string implicit none private public :: field_data_t public :: model_data_t type :: field_data_t !private integer :: pdg = 0 type(string_t), dimension(:), allocatable :: name contains procedure :: init => field_data_init procedure :: get_pdg => field_data_get_pdg end type field_data_t type :: model_data_t !private type(string_t) :: name type(field_data_t), dimension(:), allocatable :: field contains generic :: init => model_data_init procedure, private :: model_data_init generic :: get_pdg => & model_data_get_field_pdg_index procedure, private :: model_data_get_field_pdg_index generic :: get_field_ptr => & model_data_get_field_ptr_pdg procedure, private :: model_data_get_field_ptr_pdg 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, pdg) class(field_data_t), intent(out) :: prt integer, intent(in) :: pdg prt%pdg = pdg end subroutine field_data_init elemental function field_data_get_pdg (prt) result (pdg) integer :: pdg class(field_data_t), intent(in) :: prt pdg = prt%pdg end function field_data_get_pdg subroutine model_data_init (model, name, & n_field) class(model_data_t), intent(out) :: model type(string_t), intent(in) :: name integer, intent(in) :: n_field model%name = name allocate (model%field (n_field)) end subroutine model_data_init function model_data_get_field_pdg_index (model, i) result (pdg) class(model_data_t), intent(in) :: model integer, intent(in) :: i integer :: pdg pdg = model%field(i)%get_pdg () end function model_data_get_field_pdg_index function model_data_get_field_ptr_pdg (model, pdg, check) result (ptr) class(model_data_t), intent(in), target :: model integer, intent(in) :: pdg logical, intent(in), optional :: check type(field_data_t), pointer :: ptr integer :: i, pdg_abs if (pdg == 0) then ptr => null () return end if pdg_abs = abs (pdg) if (lbound(model%field, 1) /= 1) STOP 1 if (ubound(model%field, 1) /= 19) STOP 2 do i = 1, size (model%field) if (model%field(i)%get_pdg () == pdg_abs) then ptr => model%field(i) return end if end do ptr => null () end function model_data_get_field_ptr_pdg 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 if (lbound(model%field, 1) /= 1) STOP 3 if (ubound(model%field, 1) /= 19) STOP 4 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, parameter :: n_field = 19 call model%init (var_str ("SM_test"), & n_field) field => model%get_field_ptr_by_index (1) call field%init (1) end subroutine model_data_init_sm_test end module model_data module flavors use model_data implicit none private public :: flavor_t type :: flavor_t private integer :: f = 0 type(field_data_t), pointer :: field_data => null () contains generic :: init => & flavor_init0_model procedure, private :: flavor_init0_model end type flavor_t contains impure elemental subroutine flavor_init0_model (flv, f, model) class(flavor_t), intent(inout) :: flv integer, intent(in) :: f class(model_data_t), intent(in), target :: model ! Check the field l/ubound at various stages, because w/o the patch ! the bounds get mixed up. if (lbound(model%field, 1) /= 1) STOP 5 if (ubound(model%field, 1) /= 19) STOP 6 flv%f = f flv%field_data => model%get_field_ptr (f, check=.true.) end subroutine flavor_init0_model end module flavors module beams use model_data use flavors implicit none private public :: beam_1 public :: beam_2 contains subroutine beam_1 (u) integer, intent(in) :: u type(flavor_t), dimension(2) :: flv real, dimension(2) :: pol_f type(model_data_t), target :: model call model%init_sm_test () call flv%init ([1,-1], model) pol_f(1) = 0.5 end subroutine beam_1 subroutine beam_2 (u, model) integer, intent(in) :: u type(flavor_t), dimension(2) :: flv real, dimension(2) :: pol_f class(model_data_t), intent(in), target :: model call flv%init ([1,-1], model) pol_f(1) = 0.5 end subroutine beam_2 end module beams module evaluators ! This module is just here for a compile check. implicit none private type :: quantum_numbers_mask_t contains generic :: operator(.or.) => quantum_numbers_mask_or procedure, private :: quantum_numbers_mask_or end type quantum_numbers_mask_t type :: index_map_t integer, dimension(:), allocatable :: entry end type index_map_t type :: prt_mask_t logical, dimension(:), allocatable :: entry end type prt_mask_t type :: qn_mask_array_t type(quantum_numbers_mask_t), dimension(:), allocatable :: mask end type qn_mask_array_t contains elemental function quantum_numbers_mask_or (mask1, mask2) result (mask) type(quantum_numbers_mask_t) :: mask class(quantum_numbers_mask_t), intent(in) :: mask1, mask2 end function quantum_numbers_mask_or subroutine make_product_interaction & (prt_is_connected, qn_mask_in, qn_mask_rest) type(prt_mask_t), dimension(2), intent(in) :: prt_is_connected type(qn_mask_array_t), dimension(2), intent(in) :: qn_mask_in type(quantum_numbers_mask_t), intent(in) :: qn_mask_rest type(index_map_t), dimension(2) :: prt_index_in integer :: i type(quantum_numbers_mask_t), dimension(:), allocatable :: qn_mask allocate (qn_mask (2)) do i = 1, 2 qn_mask(prt_index_in(i)%entry) = & pack (qn_mask_in(i)%mask, prt_is_connected(i)%entry) & .or. qn_mask_rest ! Without the patch above line produced an ICE. end do end subroutine make_product_interaction end module evaluators program main use beams use model_data type(model_data_t) :: model call model%init_sm_test() call beam_1 (6) call beam_2 (6, model) end program main