! { dg-do run } ! ! Contributed by Juergen Reuter ! Check that pr65548 is fixed. ! module selectors type :: selector_t integer, dimension(:), allocatable :: map real, dimension(:), allocatable :: weight contains procedure :: init => selector_init end type selector_t contains subroutine selector_init (selector, weight) class(selector_t), intent(out) :: selector real, dimension(:), intent(in) :: weight real :: s integer :: n, i logical, dimension(:), allocatable :: mask s = sum (weight) allocate (mask (size (weight)), source = weight /= 0) n = count (mask) if (n > 0) then allocate (selector%map (n), & source = pack ([(i, i = 1, size (weight))], mask)) allocate (selector%weight (n), & source = pack (weight / s, mask)) else allocate (selector%map (1), source = 1) allocate (selector%weight (1), source = 0.) end if end subroutine selector_init end module selectors module phs_base type :: flavor_t contains procedure :: get_mass => flavor_get_mass end type flavor_t type :: phs_config_t integer :: n_in = 0 type(flavor_t), dimension(:,:), allocatable :: flv end type phs_config_t type :: phs_t class(phs_config_t), pointer :: config => null () real, dimension(:), allocatable :: m_in end type phs_t contains elemental function flavor_get_mass (flv) result (mass) real :: mass class(flavor_t), intent(in) :: flv mass = 42.0 end function flavor_get_mass subroutine phs_base_init (phs, phs_config) class(phs_t), intent(out) :: phs class(phs_config_t), intent(in), target :: phs_config phs%config => phs_config allocate (phs%m_in (phs%config%n_in), & source = phs_config%flv(:phs_config%n_in, 1)%get_mass ()) end subroutine phs_base_init end module phs_base module foo type :: t integer :: n real, dimension(:,:), allocatable :: val contains procedure :: make => t_make generic :: get_int => get_int_array, get_int_element procedure :: get_int_array => t_get_int_array procedure :: get_int_element => t_get_int_element end type t contains subroutine t_make (this) class(t), intent(inout) :: this real, dimension(:), allocatable :: int allocate (int (0:this%n-1), source=this%get_int()) end subroutine t_make pure function t_get_int_array (this) result (array) class(t), intent(in) :: this real, dimension(this%n) :: array array = this%val (0:this%n-1, 4) end function t_get_int_array pure function t_get_int_element (this, set) result (element) class(t), intent(in) :: this integer, intent(in) :: set real :: element element = this%val (set, 4) end function t_get_int_element end module foo module foo2 type :: t2 integer :: n character(32), dimension(:), allocatable :: md5 contains procedure :: init => t2_init end type t2 contains subroutine t2_init (this) class(t2), intent(inout) :: this character(32), dimension(:), allocatable :: md5 allocate (md5 (this%n), source=this%md5) if (md5(1) /= "tst ") STOP 1 if (md5(2) /= " ") STOP 2 if (md5(3) /= "fooblabar ") STOP 3 end subroutine t2_init end module foo2 program test use selectors use phs_base use foo use foo2 type(selector_t) :: sel type(phs_t) :: phs type(phs_config_t) :: phs_config type(t) :: o type(t2) :: o2 call sel%init([2., 0., 3., 0., 4.]) if (any(sel%map /= [1, 3, 5])) STOP 4 if (any(abs(sel%weight - [2., 3., 4.] / 9.) > 1E-6)) STOP 5 phs_config%n_in = 2 allocate (phs_config%flv (phs_config%n_in, 1)) call phs_base_init (phs, phs_config) if (any(abs(phs%m_in - [42.0, 42.0]) > 1E-6)) STOP 6 o%n = 2 allocate (o%val(0:1,4)) call o%make() o2%n = 3 allocate(o2%md5(o2%n)) o2%md5(1) = "tst" o2%md5(2) = "" o2%md5(3) = "fooblabar" call o2%init() end program test