1! Test lowering of allocatable components
2! RUN: bbc -emit-fir %s -o - | FileCheck %s
3
4module acomp
5  implicit none
6  type t
7    real :: x
8    integer :: i
9  end type
10  interface
11    subroutine takes_real_scalar(x)
12      real :: x
13    end subroutine
14    subroutine takes_char_scalar(x)
15      character(*) :: x
16    end subroutine
17    subroutine takes_derived_scalar(x)
18      import t
19      type(t) :: x
20    end subroutine
21    subroutine takes_real_array(x)
22      real :: x(:)
23    end subroutine
24    subroutine takes_char_array(x)
25      character(*) :: x(:)
26    end subroutine
27    subroutine takes_derived_array(x)
28      import t
29      type(t) :: x(:)
30    end subroutine
31    subroutine takes_real_scalar_pointer(x)
32      real, allocatable :: x
33    end subroutine
34    subroutine takes_real_array_pointer(x)
35      real, allocatable :: x(:)
36    end subroutine
37    subroutine takes_logical(x)
38      logical :: x
39    end subroutine
40  end interface
41
42  type real_a0
43    real, allocatable :: p
44  end type
45  type real_a1
46    real, allocatable :: p(:)
47  end type
48  type cst_char_a0
49    character(10), allocatable :: p
50  end type
51  type cst_char_a1
52    character(10), allocatable :: p(:)
53  end type
54  type def_char_a0
55    character(:), allocatable :: p
56  end type
57  type def_char_a1
58    character(:), allocatable :: p(:)
59  end type
60  type derived_a0
61    type(t), allocatable :: p
62  end type
63  type derived_a1
64    type(t), allocatable :: p(:)
65  end type
66
67  real, target :: real_target, real_array_target(100)
68  character(10), target :: char_target, char_array_target(100)
69
70contains
71
72! -----------------------------------------------------------------------------
73!            Test allocatable component references
74! -----------------------------------------------------------------------------
75
76! CHECK-LABEL: func @_QMacompPref_scalar_real_a(
77! CHECK-SAME: %[[arg0:.*]]: !fir.ref<!fir.type<_QMacompTreal_a0{p:!fir.box<!fir.heap<f32>>}>>{{.*}}, %[[arg1:.*]]: !fir.ref<!fir.type<_QMacompTreal_a1{p:!fir.box<!fir.heap<!fir.array<?xf32>>>}>>{{.*}}, %[[arg2:.*]]: !fir.ref<!fir.array<100x!fir.type<_QMacompTreal_a0{p:!fir.box<!fir.heap<f32>>}>>>{{.*}}, %[[arg3:.*]]: !fir.ref<!fir.array<100x!fir.type<_QMacompTreal_a1{p:!fir.box<!fir.heap<!fir.array<?xf32>>>}>>>{{.*}}) {
78subroutine ref_scalar_real_a(a0_0, a1_0, a0_1, a1_1)
79  type(real_a0) :: a0_0, a0_1(100)
80  type(real_a1) :: a1_0, a1_1(100)
81
82  ! CHECK: %[[fld:.*]] = fir.field_index p, !fir.type<_QMacompTreal_a0{p:!fir.box<!fir.heap<f32>>}>
83  ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[arg0]], %[[fld]] : (!fir.ref<!fir.type<_QMacompTreal_a0{p:!fir.box<!fir.heap<f32>>}>>, !fir.field) -> !fir.ref<!fir.box<!fir.heap<f32>>>
84  ! CHECK: %[[load:.*]] = fir.load %[[coor]] : !fir.ref<!fir.box<!fir.heap<f32>>>
85  ! CHECK: %[[addr:.*]] = fir.box_addr %[[load]] : (!fir.box<!fir.heap<f32>>) -> !fir.heap<f32>
86  ! CHECK: %[[cast:.*]] = fir.convert %[[addr]] : (!fir.heap<f32>) -> !fir.ref<f32>
87  ! CHECK: fir.call @_QPtakes_real_scalar(%[[cast]]) : (!fir.ref<f32>) -> ()
88  call takes_real_scalar(a0_0%p)
89
90  ! CHECK: %[[a0_1_coor:.*]] = fir.coordinate_of %[[arg2]], %{{.*}} : (!fir.ref<!fir.array<100x!fir.type<_QMacompTreal_a0{p:!fir.box<!fir.heap<f32>>}>>>, i64) -> !fir.ref<!fir.type<_QMacompTreal_a0{p:!fir.box<!fir.heap<f32>>}>>
91  ! CHECK: %[[fld:.*]] = fir.field_index p, !fir.type<_QMacompTreal_a0{p:!fir.box<!fir.heap<f32>>}>
92  ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[a0_1_coor]], %[[fld]] : (!fir.ref<!fir.type<_QMacompTreal_a0{p:!fir.box<!fir.heap<f32>>}>>, !fir.field) -> !fir.ref<!fir.box<!fir.heap<f32>>>
93  ! CHECK: %[[load:.*]] = fir.load %[[coor]] : !fir.ref<!fir.box<!fir.heap<f32>>>
94  ! CHECK: %[[addr:.*]] = fir.box_addr %[[load]] : (!fir.box<!fir.heap<f32>>) -> !fir.heap<f32>
95  ! CHECK: %[[cast:.*]] = fir.convert %[[addr]] : (!fir.heap<f32>) -> !fir.ref<f32>
96  ! CHECK: fir.call @_QPtakes_real_scalar(%[[cast]]) : (!fir.ref<f32>) -> ()
97  call takes_real_scalar(a0_1(5)%p)
98
99  ! CHECK: %[[fld:.*]] = fir.field_index p, !fir.type<_QMacompTreal_a1{p:!fir.box<!fir.heap<!fir.array<?xf32>>>}>
100  ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[arg1]], %[[fld]] : (!fir.ref<!fir.type<_QMacompTreal_a1{p:!fir.box<!fir.heap<!fir.array<?xf32>>>}>>, !fir.field) -> !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
101  ! CHECK: %[[box:.*]] = fir.load %[[coor]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
102  ! CHECK-DAG: %[[addr:.*]] = fir.box_addr %[[box]] : (!fir.box<!fir.heap<!fir.array<?xf32>>>) -> !fir.heap<!fir.array<?xf32>>
103  ! CHECK-DAG: %[[dims:.*]]:3 = fir.box_dims %[[box]], %c0{{.*}} : (!fir.box<!fir.heap<!fir.array<?xf32>>>, index) -> (index, index, index)
104  ! CHECK: %[[lb:.*]] = fir.convert %[[dims]]#0 : (index) -> i64
105  ! CHECK: %[[index:.*]] = arith.subi %c7{{.*}}, %[[lb]] : i64
106  ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[addr]], %[[index]] : (!fir.heap<!fir.array<?xf32>>, i64) -> !fir.ref<f32>
107  ! CHECK: fir.call @_QPtakes_real_scalar(%[[coor]]) : (!fir.ref<f32>) -> ()
108  call takes_real_scalar(a1_0%p(7))
109
110  ! CHECK: %[[a1_1_coor:.*]] = fir.coordinate_of %[[arg3]], %{{.*}} : (!fir.ref<!fir.array<100x!fir.type<_QMacompTreal_a1{p:!fir.box<!fir.heap<!fir.array<?xf32>>>}>>>, i64) -> !fir.ref<!fir.type<_QMacompTreal_a1{p:!fir.box<!fir.heap<!fir.array<?xf32>>>}>>
111  ! CHECK: %[[fld:.*]] = fir.field_index p, !fir.type<_QMacompTreal_a1{p:!fir.box<!fir.heap<!fir.array<?xf32>>>}>
112  ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[a1_1_coor]], %[[fld]] : (!fir.ref<!fir.type<_QMacompTreal_a1{p:!fir.box<!fir.heap<!fir.array<?xf32>>>}>>, !fir.field) -> !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
113  ! CHECK: %[[box:.*]] = fir.load %[[coor]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
114  ! CHECK-DAG: %[[addr:.*]] = fir.box_addr %[[box]] : (!fir.box<!fir.heap<!fir.array<?xf32>>>) -> !fir.heap<!fir.array<?xf32>>
115  ! CHECK-DAG: %[[dims:.*]]:3 = fir.box_dims %[[box]], %c0{{.*}} : (!fir.box<!fir.heap<!fir.array<?xf32>>>, index) -> (index, index, index)
116  ! CHECK: %[[lb:.*]] = fir.convert %[[dims]]#0 : (index) -> i64
117  ! CHECK: %[[index:.*]] = arith.subi %c7{{.*}}, %[[lb]] : i64
118  ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[addr]], %[[index]] : (!fir.heap<!fir.array<?xf32>>, i64) -> !fir.ref<f32>
119  ! CHECK: fir.call @_QPtakes_real_scalar(%[[coor]]) : (!fir.ref<f32>) -> ()
120  call takes_real_scalar(a1_1(5)%p(7))
121end subroutine
122
123! CHECK-LABEL: func @_QMacompPref_array_real_a(
124! CHECK-SAME:        %[[VAL_0:.*]]: !fir.ref<!fir.type<_QMacompTreal_a1{p:!fir.box<!fir.heap<!fir.array<?xf32>>>}>>{{.*}}, %[[VAL_1:.*]]: !fir.ref<!fir.array<100x!fir.type<_QMacompTreal_a1{p:!fir.box<!fir.heap<!fir.array<?xf32>>>}>>>{{.*}}) {
125! CHECK:         %[[VAL_2:.*]] = fir.field_index p, !fir.type<_QMacompTreal_a1{p:!fir.box<!fir.heap<!fir.array<?xf32>>>}>
126! CHECK:         %[[VAL_3:.*]] = fir.coordinate_of %[[VAL_0]], %[[VAL_2]] : (!fir.ref<!fir.type<_QMacompTreal_a1{p:!fir.box<!fir.heap<!fir.array<?xf32>>>}>>, !fir.field) -> !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
127! CHECK:         %[[VAL_4:.*]] = fir.load %[[VAL_3]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
128! CHECK:         %[[VAL_5:.*]] = arith.constant 0 : index
129! CHECK:         %[[VAL_6:.*]]:3 = fir.box_dims %[[VAL_4]], %[[VAL_5]] : (!fir.box<!fir.heap<!fir.array<?xf32>>>, index) -> (index, index, index)
130! CHECK:         %[[VAL_7:.*]] = fir.box_addr %[[VAL_4]] : (!fir.box<!fir.heap<!fir.array<?xf32>>>) -> !fir.heap<!fir.array<?xf32>>
131! CHECK:         %[[VAL_8:.*]] = arith.constant 20 : i64
132! CHECK:         %[[VAL_9:.*]] = fir.convert %[[VAL_8]] : (i64) -> index
133! CHECK:         %[[VAL_10:.*]] = arith.constant 2 : i64
134! CHECK:         %[[VAL_11:.*]] = fir.convert %[[VAL_10]] : (i64) -> index
135! CHECK:         %[[VAL_12:.*]] = arith.constant 50 : i64
136! CHECK:         %[[VAL_13:.*]] = fir.convert %[[VAL_12]] : (i64) -> index
137! CHECK:         %[[VAL_14:.*]] = fir.shape_shift %[[VAL_6]]#0, %[[VAL_6]]#1 : (index, index) -> !fir.shapeshift<1>
138! CHECK:         %[[VAL_15:.*]] = fir.slice %[[VAL_9]], %[[VAL_13]], %[[VAL_11]] : (index, index, index) -> !fir.slice<1>
139! CHECK:         %[[VAL_16:.*]] = fir.embox %[[VAL_7]](%[[VAL_14]]) {{\[}}%[[VAL_15]]] : (!fir.heap<!fir.array<?xf32>>, !fir.shapeshift<1>, !fir.slice<1>) -> !fir.box<!fir.array<?xf32>>
140! CHECK:         fir.call @_QPtakes_real_array(%[[VAL_16]]) : (!fir.box<!fir.array<?xf32>>) -> ()
141! CHECK:         %[[VAL_17:.*]] = arith.constant 5 : i64
142! CHECK:         %[[VAL_18:.*]] = arith.constant 1 : i64
143! CHECK:         %[[VAL_19:.*]] = arith.subi %[[VAL_17]], %[[VAL_18]] : i64
144! CHECK:         %[[VAL_20:.*]] = fir.coordinate_of %[[VAL_1]], %[[VAL_19]] : (!fir.ref<!fir.array<100x!fir.type<_QMacompTreal_a1{p:!fir.box<!fir.heap<!fir.array<?xf32>>>}>>>, i64) -> !fir.ref<!fir.type<_QMacompTreal_a1{p:!fir.box<!fir.heap<!fir.array<?xf32>>>}>>
145! CHECK:         %[[VAL_21:.*]] = fir.field_index p, !fir.type<_QMacompTreal_a1{p:!fir.box<!fir.heap<!fir.array<?xf32>>>}>
146! CHECK:         %[[VAL_22:.*]] = fir.coordinate_of %[[VAL_20]], %[[VAL_21]] : (!fir.ref<!fir.type<_QMacompTreal_a1{p:!fir.box<!fir.heap<!fir.array<?xf32>>>}>>, !fir.field) -> !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
147! CHECK:         %[[VAL_23:.*]] = fir.load %[[VAL_22]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
148! CHECK:         %[[VAL_24:.*]] = arith.constant 0 : index
149! CHECK:         %[[VAL_25:.*]]:3 = fir.box_dims %[[VAL_23]], %[[VAL_24]] : (!fir.box<!fir.heap<!fir.array<?xf32>>>, index) -> (index, index, index)
150! CHECK:         %[[VAL_26:.*]] = fir.box_addr %[[VAL_23]] : (!fir.box<!fir.heap<!fir.array<?xf32>>>) -> !fir.heap<!fir.array<?xf32>>
151! CHECK:         %[[VAL_27:.*]] = arith.constant 20 : i64
152! CHECK:         %[[VAL_28:.*]] = fir.convert %[[VAL_27]] : (i64) -> index
153! CHECK:         %[[VAL_29:.*]] = arith.constant 2 : i64
154! CHECK:         %[[VAL_30:.*]] = fir.convert %[[VAL_29]] : (i64) -> index
155! CHECK:         %[[VAL_31:.*]] = arith.constant 50 : i64
156! CHECK:         %[[VAL_32:.*]] = fir.convert %[[VAL_31]] : (i64) -> index
157! CHECK:         %[[VAL_33:.*]] = fir.shape_shift %[[VAL_25]]#0, %[[VAL_25]]#1 : (index, index) -> !fir.shapeshift<1>
158! CHECK:         %[[VAL_34:.*]] = fir.slice %[[VAL_28]], %[[VAL_32]], %[[VAL_30]] : (index, index, index) -> !fir.slice<1>
159! CHECK:         %[[VAL_35:.*]] = fir.embox %[[VAL_26]](%[[VAL_33]]) {{\[}}%[[VAL_34]]] : (!fir.heap<!fir.array<?xf32>>, !fir.shapeshift<1>, !fir.slice<1>) -> !fir.box<!fir.array<?xf32>>
160! CHECK:         fir.call @_QPtakes_real_array(%[[VAL_35]]) : (!fir.box<!fir.array<?xf32>>) -> ()
161! CHECK:         return
162! CHECK:       }
163
164subroutine ref_array_real_a(a1_0, a1_1)
165  type(real_a1) :: a1_0, a1_1(100)
166  call takes_real_array(a1_0%p(20:50:2))
167  call takes_real_array(a1_1(5)%p(20:50:2))
168end subroutine
169
170! CHECK-LABEL: func @_QMacompPref_scalar_cst_char_a
171! CHECK-SAME: (%[[a0_0:.*]]: {{.*}}, %[[a1_0:.*]]: {{.*}}, %[[a0_1:.*]]: {{.*}}, %[[a1_1:.*]]: {{.*}})
172subroutine ref_scalar_cst_char_a(a0_0, a1_0, a0_1, a1_1)
173  type(cst_char_a0) :: a0_0, a0_1(100)
174  type(cst_char_a1) :: a1_0, a1_1(100)
175
176  ! CHECK: %[[fld:.*]] = fir.field_index p
177  ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[a0_0]], %[[fld]]
178  ! CHECK: %[[box:.*]] = fir.load %[[coor]]
179  ! CHECK: %[[addr:.*]] = fir.box_addr %[[box]]
180  ! CHECK: %[[cast:.*]] = fir.convert %[[addr]]
181  ! CHECK: %[[boxchar:.*]] = fir.emboxchar %[[cast]], %c10{{.*}}
182  ! CHECK: fir.call @_QPtakes_char_scalar(%[[boxchar]])
183  call takes_char_scalar(a0_0%p)
184
185  ! CHECK-DAG: %[[coor0:.*]] = fir.coordinate_of %[[a0_1]], %{{.*}}
186  ! CHECK-DAG: %[[fld:.*]] = fir.field_index p
187  ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[coor0]], %[[fld]]
188  ! CHECK: %[[box:.*]] = fir.load %[[coor]]
189  ! CHECK: %[[addr:.*]] = fir.box_addr %[[box]]
190  ! CHECK: %[[cast:.*]] = fir.convert %[[addr]]
191  ! CHECK: %[[boxchar:.*]] = fir.emboxchar %[[cast]], %c10{{.*}}
192  ! CHECK: fir.call @_QPtakes_char_scalar(%[[boxchar]])
193  call takes_char_scalar(a0_1(5)%p)
194
195
196  ! CHECK-DAG: %[[fld:.*]] = fir.field_index p
197  ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[a1_0]], %[[fld]]
198  ! CHECK: %[[box:.*]] = fir.load %[[coor]]
199  ! CHECK-DAG: %[[base:.*]] = fir.box_addr %[[box]]
200  ! CHECK-DAG: %[[dims:.*]]:3 = fir.box_dims %[[box]], %c0{{.*}}
201  ! CHECK: %[[lb:.*]] = fir.convert %[[dims]]#0 : (index) -> i64
202  ! CHECK: %[[index:.*]] = arith.subi %c7{{.*}}, %[[lb]] : i64
203  ! CHECK: %[[addr:.*]] = fir.coordinate_of %[[base]], %[[index]]
204  ! CHECK: %[[cast:.*]] = fir.convert %[[addr]]
205  ! CHECK: %[[boxchar:.*]] = fir.emboxchar %[[cast]], %c10{{.*}}
206  ! CHECK: fir.call @_QPtakes_char_scalar(%[[boxchar]])
207  call takes_char_scalar(a1_0%p(7))
208
209
210  ! CHECK-DAG: %[[coor0:.*]] = fir.coordinate_of %[[a1_1]], %{{.*}}
211  ! CHECK-DAG: %[[fld:.*]] = fir.field_index p
212  ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[coor0]], %[[fld]]
213  ! CHECK: %[[box:.*]] = fir.load %[[coor]]
214  ! CHECK-DAG: %[[base:.*]] = fir.box_addr %[[box]]
215  ! CHECK-DAG: %[[dims:.*]]:3 = fir.box_dims %[[box]], %c0{{.*}}
216  ! CHECK: %[[lb:.*]] = fir.convert %[[dims]]#0 : (index) -> i64
217  ! CHECK: %[[index:.*]] = arith.subi %c7{{.*}}, %[[lb]] : i64
218  ! CHECK: %[[addr:.*]] = fir.coordinate_of %[[base]], %[[index]]
219  ! CHECK: %[[cast:.*]] = fir.convert %[[addr]]
220  ! CHECK: %[[boxchar:.*]] = fir.emboxchar %[[cast]], %c10{{.*}}
221  ! CHECK: fir.call @_QPtakes_char_scalar(%[[boxchar]])
222  call takes_char_scalar(a1_1(5)%p(7))
223
224end subroutine
225
226! CHECK-LABEL: func @_QMacompPref_scalar_def_char_a
227! CHECK-SAME: (%[[a0_0:.*]]: {{.*}}, %[[a1_0:.*]]: {{.*}}, %[[a0_1:.*]]: {{.*}}, %[[a1_1:.*]]: {{.*}})
228subroutine ref_scalar_def_char_a(a0_0, a1_0, a0_1, a1_1)
229  type(def_char_a0) :: a0_0, a0_1(100)
230  type(def_char_a1) :: a1_0, a1_1(100)
231
232  ! CHECK: %[[fld:.*]] = fir.field_index p
233  ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[a0_0]], %[[fld]]
234  ! CHECK: %[[box:.*]] = fir.load %[[coor]]
235  ! CHECK-DAG: %[[len:.*]] = fir.box_elesize %[[box]]
236  ! CHECK-DAG: %[[addr:.*]] = fir.box_addr %[[box]]
237  ! CHECK-DAG: %[[cast:.*]] = fir.convert %[[addr]]
238  ! CHECK: %[[boxchar:.*]] = fir.emboxchar %[[cast]], %[[len]]
239  ! CHECK: fir.call @_QPtakes_char_scalar(%[[boxchar]])
240  call takes_char_scalar(a0_0%p)
241
242  ! CHECK-DAG: %[[coor0:.*]] = fir.coordinate_of %[[a0_1]], %{{.*}}
243  ! CHECK-DAG: %[[fld:.*]] = fir.field_index p
244  ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[coor0]], %[[fld]]
245  ! CHECK: %[[box:.*]] = fir.load %[[coor]]
246  ! CHECK-DAG: %[[len:.*]] = fir.box_elesize %[[box]]
247  ! CHECK-DAG: %[[addr:.*]] = fir.box_addr %[[box]]
248  ! CHECK-DAG: %[[cast:.*]] = fir.convert %[[addr]]
249  ! CHECK: %[[boxchar:.*]] = fir.emboxchar %[[cast]], %[[len]]
250  ! CHECK: fir.call @_QPtakes_char_scalar(%[[boxchar]])
251  call takes_char_scalar(a0_1(5)%p)
252
253
254  ! CHECK-DAG: %[[fld:.*]] = fir.field_index p
255  ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[a1_0]], %[[fld]]
256  ! CHECK: %[[box:.*]] = fir.load %[[coor]]
257  ! CHECK-DAG: %[[dims:.*]]:3 = fir.box_dims %[[box]], %c0{{.*}}
258  ! CHECK-DAG: %[[len:.*]] = fir.box_elesize %[[box]]
259  ! CHECK-DAG: %[[base:.*]] = fir.box_addr %[[box]]
260  ! CHECK: %[[cast:.*]] = fir.convert %[[base]] : (!fir.heap<!fir.array<?x!fir.char<1,?>>>) -> !fir.ref<!fir.array<?x!fir.char<1,?>>>
261  ! CHECK: %[[c7:.*]] = fir.convert %c7{{.*}} : (i64) -> index
262  ! CHECK: %[[sub:.*]] = arith.subi %[[c7]], %[[dims]]#0 : index
263  ! CHECK: %[[mul:.*]] = arith.muli %[[len]], %[[sub]] : index
264  ! CHECK: %[[offset:.*]] = arith.addi %[[mul]], %c0{{.*}} : index
265  ! CHECK: %[[cnvt:.*]] = fir.convert %[[cast]]
266  ! CHECK: %[[addr:.*]] = fir.coordinate_of %[[cnvt]], %[[offset]]
267  ! CHECK: %[[cnvt:.*]] = fir.convert %[[addr]]
268  ! CHECK: %[[boxchar:.*]] = fir.emboxchar %[[cnvt]], %[[len]]
269  ! CHECK: fir.call @_QPtakes_char_scalar(%[[boxchar]])
270  call takes_char_scalar(a1_0%p(7))
271
272
273  ! CHECK-DAG: %[[coor0:.*]] = fir.coordinate_of %[[a1_1]], %{{.*}}
274  ! CHECK-DAG: %[[fld:.*]] = fir.field_index p
275  ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[coor0]], %[[fld]]
276  ! CHECK: %[[box:.*]] = fir.load %[[coor]]
277  ! CHECK-DAG: %[[dims:.*]]:3 = fir.box_dims %[[box]], %c0{{.*}}
278  ! CHECK-DAG: %[[len:.*]] = fir.box_elesize %[[box]]
279  ! CHECK-DAG: %[[base:.*]] = fir.box_addr %[[box]]
280  ! CHECK: %[[cast:.*]] = fir.convert %[[base]] : (!fir.heap<!fir.array<?x!fir.char<1,?>>>) -> !fir.ref<!fir.array<?x!fir.char<1,?>>>
281  ! CHECK: %[[c7:.*]] = fir.convert %c7{{.*}} : (i64) -> index
282  ! CHECK: %[[sub:.*]] = arith.subi %[[c7]], %[[dims]]#0 : index
283  ! CHECK: %[[mul:.*]] = arith.muli %[[len]], %[[sub]] : index
284  ! CHECK: %[[offset:.*]] = arith.addi %[[mul]], %c0{{.*}} : index
285  ! CHECK: %[[cnvt:.*]] = fir.convert %[[cast]]
286  ! CHECK: %[[addr:.*]] = fir.coordinate_of %[[cnvt]], %[[offset]]
287  ! CHECK: %[[cnvt:.*]] = fir.convert %[[addr]]
288  ! CHECK: %[[boxchar:.*]] = fir.emboxchar %[[cnvt]], %[[len]]
289  ! CHECK: fir.call @_QPtakes_char_scalar(%[[boxchar]])
290  call takes_char_scalar(a1_1(5)%p(7))
291
292end subroutine
293
294! CHECK-LABEL: func @_QMacompPref_scalar_derived
295! CHECK-SAME: (%[[a0_0:.*]]: {{.*}}, %[[a1_0:.*]]: {{.*}}, %[[a0_1:.*]]: {{.*}}, %[[a1_1:.*]]: {{.*}})
296subroutine ref_scalar_derived(a0_0, a1_0, a0_1, a1_1)
297  type(derived_a0) :: a0_0, a0_1(100)
298  type(derived_a1) :: a1_0, a1_1(100)
299
300  ! CHECK: %[[fld:.*]] = fir.field_index p
301  ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[a0_0]], %[[fld]]
302  ! CHECK: %[[box:.*]] = fir.load %[[coor]]
303  ! CHECK: %[[fldx:.*]] = fir.field_index x
304  ! CHECK: %[[addr:.*]] = fir.coordinate_of %[[box]], %[[fldx]]
305  ! CHECK: fir.call @_QPtakes_real_scalar(%[[addr]])
306  call takes_real_scalar(a0_0%p%x)
307
308  ! CHECK-DAG: %[[coor0:.*]] = fir.coordinate_of %[[a0_1]], %{{.*}}
309  ! CHECK-DAG: %[[fld:.*]] = fir.field_index p
310  ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[coor0]], %[[fld]]
311  ! CHECK: %[[box:.*]] = fir.load %[[coor]]
312  ! CHECK: %[[fldx:.*]] = fir.field_index x
313  ! CHECK: %[[addr:.*]] = fir.coordinate_of %[[box]], %[[fldx]]
314  ! CHECK: fir.call @_QPtakes_real_scalar(%[[addr]])
315  call takes_real_scalar(a0_1(5)%p%x)
316
317  ! CHECK: %[[fld:.*]] = fir.field_index p
318  ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[a1_0]], %[[fld]]
319  ! CHECK: %[[box:.*]] = fir.load %[[coor]]
320  ! CHECK: %[[dims:.*]]:3 = fir.box_dims %[[box]], %c0{{.*}}
321  ! CHECK: %[[lb:.*]] = fir.convert %[[dims]]#0 : (index) -> i64
322  ! CHECK: %[[index:.*]] = arith.subi %c7{{.*}}, %[[lb]] : i64
323  ! CHECK: %[[elem:.*]] = fir.coordinate_of %[[box]], %[[index]]
324  ! CHECK: %[[fldx:.*]] = fir.field_index x
325  ! CHECK: %[[addr:.*]] = fir.coordinate_of %[[elem]], %[[fldx]]
326  ! CHECK: fir.call @_QPtakes_real_scalar(%[[addr]])
327  call takes_real_scalar(a1_0%p(7)%x)
328
329  ! CHECK-DAG: %[[coor0:.*]] = fir.coordinate_of %[[a1_1]], %{{.*}}
330  ! CHECK-DAG: %[[fld:.*]] = fir.field_index p
331  ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[coor0]], %[[fld]]
332  ! CHECK: %[[box:.*]] = fir.load %[[coor]]
333  ! CHECK: %[[dims:.*]]:3 = fir.box_dims %[[box]], %c0{{.*}}
334  ! CHECK: %[[lb:.*]] = fir.convert %[[dims]]#0 : (index) -> i64
335  ! CHECK: %[[index:.*]] = arith.subi %c7{{.*}}, %[[lb]] : i64
336  ! CHECK: %[[elem:.*]] = fir.coordinate_of %[[box]], %[[index]]
337  ! CHECK: %[[fldx:.*]] = fir.field_index x
338  ! CHECK: %[[addr:.*]] = fir.coordinate_of %[[elem]], %[[fldx]]
339  ! CHECK: fir.call @_QPtakes_real_scalar(%[[addr]])
340  call takes_real_scalar(a1_1(5)%p(7)%x)
341
342end subroutine
343
344! -----------------------------------------------------------------------------
345!            Test passing allocatable component references as allocatables
346! -----------------------------------------------------------------------------
347
348! CHECK-LABEL: func @_QMacompPpass_real_a
349! CHECK-SAME: (%[[a0_0:.*]]: {{.*}}, %[[a1_0:.*]]: {{.*}}, %[[a0_1:.*]]: {{.*}}, %[[a1_1:.*]]: {{.*}})
350subroutine pass_real_a(a0_0, a1_0, a0_1, a1_1)
351  type(real_a0) :: a0_0, a0_1(100)
352  type(real_a1) :: a1_0, a1_1(100)
353  ! CHECK: %[[fld:.*]] = fir.field_index p
354  ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[a0_0]], %[[fld]]
355  ! CHECK: fir.call @_QPtakes_real_scalar_pointer(%[[coor]])
356  call takes_real_scalar_pointer(a0_0%p)
357
358  ! CHECK-DAG: %[[coor0:.*]] = fir.coordinate_of %[[a0_1]], %{{.*}}
359  ! CHECK-DAG: %[[fld:.*]] = fir.field_index p
360  ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[coor0]], %[[fld]]
361  ! CHECK: fir.call @_QPtakes_real_scalar_pointer(%[[coor]])
362  call takes_real_scalar_pointer(a0_1(5)%p)
363
364  ! CHECK: %[[fld:.*]] = fir.field_index p
365  ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[a1_0]], %[[fld]]
366  ! CHECK: fir.call @_QPtakes_real_array_pointer(%[[coor]])
367  call takes_real_array_pointer(a1_0%p)
368
369  ! CHECK-DAG: %[[coor0:.*]] = fir.coordinate_of %[[a1_1]], %{{.*}}
370  ! CHECK-DAG: %[[fld:.*]] = fir.field_index p
371  ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[coor0]], %[[fld]]
372  ! CHECK: fir.call @_QPtakes_real_array_pointer(%[[coor]])
373  call takes_real_array_pointer(a1_1(5)%p)
374end subroutine
375
376! -----------------------------------------------------------------------------
377!            Test usage in intrinsics where pointer aspect matters
378! -----------------------------------------------------------------------------
379
380! CHECK-LABEL: func @_QMacompPallocated_p
381! CHECK-SAME: (%[[a0_0:.*]]: {{.*}}, %[[a1_0:.*]]: {{.*}}, %[[a0_1:.*]]: {{.*}}, %[[a1_1:.*]]: {{.*}})
382subroutine allocated_p(a0_0, a1_0, a0_1, a1_1)
383  type(real_a0) :: a0_0, a0_1(100)
384  type(def_char_a1) :: a1_0, a1_1(100)
385  ! CHECK: %[[fld:.*]] = fir.field_index p
386  ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[a0_0]], %[[fld]]
387  ! CHECK: %[[box:.*]] = fir.load %[[coor]]
388  ! CHECK: fir.box_addr %[[box]]
389  call takes_logical(allocated(a0_0%p))
390
391  ! CHECK-DAG: %[[coor0:.*]] = fir.coordinate_of %[[a0_1]], %{{.*}}
392  ! CHECK-DAG: %[[fld:.*]] = fir.field_index p
393  ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[coor0]], %[[fld]]
394  ! CHECK: %[[box:.*]] = fir.load %[[coor]]
395  ! CHECK: fir.box_addr %[[box]]
396  call takes_logical(allocated(a0_1(5)%p))
397
398  ! CHECK: %[[fld:.*]] = fir.field_index p
399  ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[a1_0]], %[[fld]]
400  ! CHECK: %[[box:.*]] = fir.load %[[coor]]
401  ! CHECK: fir.box_addr %[[box]]
402  call takes_logical(allocated(a1_0%p))
403
404  ! CHECK-DAG: %[[coor0:.*]] = fir.coordinate_of %[[a1_1]], %{{.*}}
405  ! CHECK-DAG: %[[fld:.*]] = fir.field_index p
406  ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[coor0]], %[[fld]]
407  ! CHECK: %[[box:.*]] = fir.load %[[coor]]
408  ! CHECK: fir.box_addr %[[box]]
409  call takes_logical(allocated(a1_1(5)%p))
410end subroutine
411
412! -----------------------------------------------------------------------------
413!            Test allocation
414! -----------------------------------------------------------------------------
415
416! CHECK-LABEL: func @_QMacompPallocate_real
417! CHECK-SAME: (%[[a0_0:.*]]: {{.*}}, %[[a1_0:.*]]: {{.*}}, %[[a0_1:.*]]: {{.*}}, %[[a1_1:.*]]: {{.*}})
418subroutine allocate_real(a0_0, a1_0, a0_1, a1_1)
419  type(real_a0) :: a0_0, a0_1(100)
420  type(real_a1) :: a1_0, a1_1(100)
421  ! CHECK: %[[fld:.*]] = fir.field_index p
422  ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[a0_0]], %[[fld]]
423  ! CHECK: fir.store {{.*}} to %[[coor]]
424  allocate(a0_0%p)
425
426  ! CHECK-DAG: %[[coor0:.*]] = fir.coordinate_of %[[a0_1]], %{{.*}}
427  ! CHECK-DAG: %[[fld:.*]] = fir.field_index p
428  ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[coor0]], %[[fld]]
429  ! CHECK: fir.store {{.*}} to %[[coor]]
430  allocate(a0_1(5)%p)
431
432  ! CHECK: %[[fld:.*]] = fir.field_index p
433  ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[a1_0]], %[[fld]]
434  ! CHECK: fir.store {{.*}} to %[[coor]]
435  allocate(a1_0%p(100))
436
437  ! CHECK-DAG: %[[coor0:.*]] = fir.coordinate_of %[[a1_1]], %{{.*}}
438  ! CHECK-DAG: %[[fld:.*]] = fir.field_index p
439  ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[coor0]], %[[fld]]
440  ! CHECK: fir.store {{.*}} to %[[coor]]
441  allocate(a1_1(5)%p(100))
442end subroutine
443
444! CHECK-LABEL: func @_QMacompPallocate_cst_char
445! CHECK-SAME: (%[[a0_0:.*]]: {{.*}}, %[[a1_0:.*]]: {{.*}}, %[[a0_1:.*]]: {{.*}}, %[[a1_1:.*]]: {{.*}})
446subroutine allocate_cst_char(a0_0, a1_0, a0_1, a1_1)
447  type(cst_char_a0) :: a0_0, a0_1(100)
448  type(cst_char_a1) :: a1_0, a1_1(100)
449  ! CHECK: %[[fld:.*]] = fir.field_index p
450  ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[a0_0]], %[[fld]]
451  ! CHECK: fir.store {{.*}} to %[[coor]]
452  allocate(a0_0%p)
453
454  ! CHECK-DAG: %[[coor0:.*]] = fir.coordinate_of %[[a0_1]], %{{.*}}
455  ! CHECK-DAG: %[[fld:.*]] = fir.field_index p
456  ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[coor0]], %[[fld]]
457  ! CHECK: fir.store {{.*}} to %[[coor]]
458  allocate(a0_1(5)%p)
459
460  ! CHECK: %[[fld:.*]] = fir.field_index p
461  ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[a1_0]], %[[fld]]
462  ! CHECK: fir.store {{.*}} to %[[coor]]
463  allocate(a1_0%p(100))
464
465  ! CHECK-DAG: %[[coor0:.*]] = fir.coordinate_of %[[a1_1]], %{{.*}}
466  ! CHECK-DAG: %[[fld:.*]] = fir.field_index p
467  ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[coor0]], %[[fld]]
468  ! CHECK: fir.store {{.*}} to %[[coor]]
469  allocate(a1_1(5)%p(100))
470end subroutine
471
472! CHECK-LABEL: func @_QMacompPallocate_def_char
473! CHECK-SAME: (%[[a0_0:.*]]: {{.*}}, %[[a1_0:.*]]: {{.*}}, %[[a0_1:.*]]: {{.*}}, %[[a1_1:.*]]: {{.*}})
474subroutine allocate_def_char(a0_0, a1_0, a0_1, a1_1)
475  type(def_char_a0) :: a0_0, a0_1(100)
476  type(def_char_a1) :: a1_0, a1_1(100)
477  ! CHECK: %[[fld:.*]] = fir.field_index p
478  ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[a0_0]], %[[fld]]
479  ! CHECK: fir.store {{.*}} to %[[coor]]
480  allocate(character(18)::a0_0%p)
481
482  ! CHECK-DAG: %[[coor0:.*]] = fir.coordinate_of %[[a0_1]], %{{.*}}
483  ! CHECK-DAG: %[[fld:.*]] = fir.field_index p
484  ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[coor0]], %[[fld]]
485  ! CHECK: fir.store {{.*}} to %[[coor]]
486  allocate(character(18)::a0_1(5)%p)
487
488  ! CHECK: %[[fld:.*]] = fir.field_index p
489  ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[a1_0]], %[[fld]]
490  ! CHECK: fir.store {{.*}} to %[[coor]]
491  allocate(character(18)::a1_0%p(100))
492
493  ! CHECK-DAG: %[[coor0:.*]] = fir.coordinate_of %[[a1_1]], %{{.*}}
494  ! CHECK-DAG: %[[fld:.*]] = fir.field_index p
495  ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[coor0]], %[[fld]]
496  ! CHECK: fir.store {{.*}} to %[[coor]]
497  allocate(character(18)::a1_1(5)%p(100))
498end subroutine
499
500! -----------------------------------------------------------------------------
501!            Test deallocation
502! -----------------------------------------------------------------------------
503
504! CHECK-LABEL: func @_QMacompPdeallocate_real
505! CHECK-SAME: (%[[a0_0:.*]]: {{.*}}, %[[a1_0:.*]]: {{.*}}, %[[a0_1:.*]]: {{.*}}, %[[a1_1:.*]]: {{.*}})
506subroutine deallocate_real(a0_0, a1_0, a0_1, a1_1)
507  type(real_a0) :: a0_0, a0_1(100)
508  type(real_a1) :: a1_0, a1_1(100)
509  ! CHECK: %[[fld:.*]] = fir.field_index p
510  ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[a0_0]], %[[fld]]
511  ! CHECK: fir.store {{.*}} to %[[coor]]
512  deallocate(a0_0%p)
513
514  ! CHECK-DAG: %[[coor0:.*]] = fir.coordinate_of %[[a0_1]], %{{.*}}
515  ! CHECK-DAG: %[[fld:.*]] = fir.field_index p
516  ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[coor0]], %[[fld]]
517  ! CHECK: fir.store {{.*}} to %[[coor]]
518  deallocate(a0_1(5)%p)
519
520  ! CHECK: %[[fld:.*]] = fir.field_index p
521  ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[a1_0]], %[[fld]]
522  ! CHECK: fir.store {{.*}} to %[[coor]]
523  deallocate(a1_0%p)
524
525  ! CHECK-DAG: %[[coor0:.*]] = fir.coordinate_of %[[a1_1]], %{{.*}}
526  ! CHECK-DAG: %[[fld:.*]] = fir.field_index p
527  ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[coor0]], %[[fld]]
528  ! CHECK: fir.store {{.*}} to %[[coor]]
529  deallocate(a1_1(5)%p)
530end subroutine
531
532! -----------------------------------------------------------------------------
533!            Test a recursive derived type reference
534! -----------------------------------------------------------------------------
535
536! CHECK: func @_QMacompPtest_recursive
537! CHECK-SAME: (%[[x:.*]]: {{.*}})
538subroutine test_recursive(x)
539  type t
540    integer :: i
541    type(t), allocatable :: next
542  end type
543  type(t) :: x
544
545  ! CHECK: %[[fldNext1:.*]] = fir.field_index next
546  ! CHECK: %[[next1:.*]] = fir.coordinate_of %[[x]], %[[fldNext1]]
547  ! CHECK: %[[nextBox1:.*]] = fir.load %[[next1]]
548  ! CHECK: %[[fldNext2:.*]] = fir.field_index next
549  ! CHECK: %[[next2:.*]] = fir.coordinate_of %[[nextBox1]], %[[fldNext2]]
550  ! CHECK: %[[nextBox2:.*]] = fir.load %[[next2]]
551  ! CHECK: %[[fldNext3:.*]] = fir.field_index next
552  ! CHECK: %[[next3:.*]] = fir.coordinate_of %[[nextBox2]], %[[fldNext3]]
553  ! CHECK: %[[nextBox3:.*]] = fir.load %[[next3]]
554  ! CHECK: %[[fldi:.*]] = fir.field_index i
555  ! CHECK: %[[i:.*]] = fir.coordinate_of %[[nextBox3]], %[[fldi]]
556  ! CHECK: %[[nextBox3:.*]] = fir.load %[[i]] : !fir.ref<i32>
557  print *, x%next%next%next%i
558end subroutine
559
560end module
561