summaryrefslogtreecommitdiff
path: root/gcc/testsuite/gfortran.dg/allocate_with_source_6.f90
blob: 7f2473aafd92f21ad76394e9320beaacfaebd30a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
! { dg-do  run }
! { dg-options "-fbounds-check" }
!
! Contributed by Juergen Reuter
! Check that pr65548 is fixed and that the ICE is gone, when bounds-check
! is requested.
!

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                             ") call abort()
    if (md5(2) /= "                                ") call abort()
    if (md5(3) /= "fooblabar                       ") call abort()
  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])) call abort()
  if (any(abs(sel%weight - [2., 3., 4.] / 9.) > 1E-6)) call abort()

  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)) call abort()

  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