blob: 5f7b36c0269407a8c3a2caf451ec875bc0993a2c [file] [log] [blame]
! { 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 <juergen.reuter@desy.de>
!
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" } }