[flang] Accept polymorphic component element in storage_size
[llvm-project.git] / flang / test / Lower / derived-allocatable-components.f90
blobced1712543f9c3376de41b29072eab676c584b6a
1 ! Test lowering of allocatable components
2 ! RUN: bbc -emit-fir %s -o - | FileCheck %s
4 module 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
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
67 real, target :: real_target, real_array_target(100)
68 character(10), target :: char_target, char_array_target(100)
70 contains
72 ! -----------------------------------------------------------------------------
73 ! Test allocatable component references
74 ! -----------------------------------------------------------------------------
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>>>}>>>{{.*}}) {
78 subroutine 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)
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)
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)
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))
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))
121 end subroutine
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<16xf32>>
140 ! CHECK: %[[VAL_16_NEW:.*]] = fir.convert %[[VAL_16]] : (!fir.box<!fir.array<16xf32>>) -> !fir.box<!fir.array<?xf32>>
141 ! CHECK: fir.call @_QPtakes_real_array(%[[VAL_16_NEW]]) {{.*}}: (!fir.box<!fir.array<?xf32>>) -> ()
142 ! CHECK: %[[VAL_17:.*]] = arith.constant 5 : i64
143 ! CHECK: %[[VAL_18:.*]] = arith.constant 1 : i64
144 ! CHECK: %[[VAL_19:.*]] = arith.subi %[[VAL_17]], %[[VAL_18]] : i64
145 ! 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>>>}>>
146 ! CHECK: %[[VAL_21:.*]] = fir.field_index p, !fir.type<_QMacompTreal_a1{p:!fir.box<!fir.heap<!fir.array<?xf32>>>}>
147 ! 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>>>>
148 ! CHECK: %[[VAL_23:.*]] = fir.load %[[VAL_22]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
149 ! CHECK: %[[VAL_24:.*]] = arith.constant 0 : index
150 ! CHECK: %[[VAL_25:.*]]:3 = fir.box_dims %[[VAL_23]], %[[VAL_24]] : (!fir.box<!fir.heap<!fir.array<?xf32>>>, index) -> (index, index, index)
151 ! CHECK: %[[VAL_26:.*]] = fir.box_addr %[[VAL_23]] : (!fir.box<!fir.heap<!fir.array<?xf32>>>) -> !fir.heap<!fir.array<?xf32>>
152 ! CHECK: %[[VAL_27:.*]] = arith.constant 20 : i64
153 ! CHECK: %[[VAL_28:.*]] = fir.convert %[[VAL_27]] : (i64) -> index
154 ! CHECK: %[[VAL_29:.*]] = arith.constant 2 : i64
155 ! CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_29]] : (i64) -> index
156 ! CHECK: %[[VAL_31:.*]] = arith.constant 50 : i64
157 ! CHECK: %[[VAL_32:.*]] = fir.convert %[[VAL_31]] : (i64) -> index
158 ! CHECK: %[[VAL_33:.*]] = fir.shape_shift %[[VAL_25]]#0, %[[VAL_25]]#1 : (index, index) -> !fir.shapeshift<1>
159 ! CHECK: %[[VAL_34:.*]] = fir.slice %[[VAL_28]], %[[VAL_32]], %[[VAL_30]] : (index, index, index) -> !fir.slice<1>
160 ! 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<16xf32>>
161 ! CHECK: %[[VAL_35_NEW:.*]] = fir.convert %[[VAL_35]] : (!fir.box<!fir.array<16xf32>>) -> !fir.box<!fir.array<?xf32>>
162 ! CHECK: fir.call @_QPtakes_real_array(%[[VAL_35_NEW]]) {{.*}}: (!fir.box<!fir.array<?xf32>>) -> ()
163 ! CHECK: return
164 ! CHECK: }
166 subroutine ref_array_real_a(a1_0, a1_1)
167 type(real_a1) :: a1_0, a1_1(100)
168 call takes_real_array(a1_0%p(20:50:2))
169 call takes_real_array(a1_1(5)%p(20:50:2))
170 end subroutine
172 ! CHECK-LABEL: func @_QMacompPref_scalar_cst_char_a
173 ! CHECK-SAME: (%[[a0_0:.*]]: {{.*}}, %[[a1_0:.*]]: {{.*}}, %[[a0_1:.*]]: {{.*}}, %[[a1_1:.*]]: {{.*}})
174 subroutine ref_scalar_cst_char_a(a0_0, a1_0, a0_1, a1_1)
175 type(cst_char_a0) :: a0_0, a0_1(100)
176 type(cst_char_a1) :: a1_0, a1_1(100)
178 ! CHECK: %[[fld:.*]] = fir.field_index p
179 ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[a0_0]], %[[fld]]
180 ! CHECK: %[[box:.*]] = fir.load %[[coor]]
181 ! CHECK: %[[addr:.*]] = fir.box_addr %[[box]]
182 ! CHECK: %[[cast:.*]] = fir.convert %[[addr]]
183 ! CHECK: %[[boxchar:.*]] = fir.emboxchar %[[cast]], %c10{{.*}}
184 ! CHECK: fir.call @_QPtakes_char_scalar(%[[boxchar]])
185 call takes_char_scalar(a0_0%p)
187 ! CHECK-DAG: %[[coor0:.*]] = fir.coordinate_of %[[a0_1]], %{{.*}}
188 ! CHECK-DAG: %[[fld:.*]] = fir.field_index p
189 ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[coor0]], %[[fld]]
190 ! CHECK: %[[box:.*]] = fir.load %[[coor]]
191 ! CHECK: %[[addr:.*]] = fir.box_addr %[[box]]
192 ! CHECK: %[[cast:.*]] = fir.convert %[[addr]]
193 ! CHECK: %[[boxchar:.*]] = fir.emboxchar %[[cast]], %c10{{.*}}
194 ! CHECK: fir.call @_QPtakes_char_scalar(%[[boxchar]])
195 call takes_char_scalar(a0_1(5)%p)
198 ! CHECK-DAG: %[[fld:.*]] = fir.field_index p
199 ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[a1_0]], %[[fld]]
200 ! CHECK: %[[box:.*]] = fir.load %[[coor]]
201 ! CHECK-DAG: %[[base:.*]] = fir.box_addr %[[box]]
202 ! CHECK-DAG: %[[dims:.*]]:3 = fir.box_dims %[[box]], %c0{{.*}}
203 ! CHECK: %[[lb:.*]] = fir.convert %[[dims]]#0 : (index) -> i64
204 ! CHECK: %[[index:.*]] = arith.subi %c7{{.*}}, %[[lb]] : i64
205 ! CHECK: %[[addr:.*]] = fir.coordinate_of %[[base]], %[[index]]
206 ! CHECK: %[[cast:.*]] = fir.convert %[[addr]]
207 ! CHECK: %[[boxchar:.*]] = fir.emboxchar %[[cast]], %c10{{.*}}
208 ! CHECK: fir.call @_QPtakes_char_scalar(%[[boxchar]])
209 call takes_char_scalar(a1_0%p(7))
212 ! CHECK-DAG: %[[coor0:.*]] = fir.coordinate_of %[[a1_1]], %{{.*}}
213 ! CHECK-DAG: %[[fld:.*]] = fir.field_index p
214 ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[coor0]], %[[fld]]
215 ! CHECK: %[[box:.*]] = fir.load %[[coor]]
216 ! CHECK-DAG: %[[base:.*]] = fir.box_addr %[[box]]
217 ! CHECK-DAG: %[[dims:.*]]:3 = fir.box_dims %[[box]], %c0{{.*}}
218 ! CHECK: %[[lb:.*]] = fir.convert %[[dims]]#0 : (index) -> i64
219 ! CHECK: %[[index:.*]] = arith.subi %c7{{.*}}, %[[lb]] : i64
220 ! CHECK: %[[addr:.*]] = fir.coordinate_of %[[base]], %[[index]]
221 ! CHECK: %[[cast:.*]] = fir.convert %[[addr]]
222 ! CHECK: %[[boxchar:.*]] = fir.emboxchar %[[cast]], %c10{{.*}}
223 ! CHECK: fir.call @_QPtakes_char_scalar(%[[boxchar]])
224 call takes_char_scalar(a1_1(5)%p(7))
226 end subroutine
228 ! CHECK-LABEL: func @_QMacompPref_scalar_def_char_a
229 ! CHECK-SAME: (%[[a0_0:.*]]: {{.*}}, %[[a1_0:.*]]: {{.*}}, %[[a0_1:.*]]: {{.*}}, %[[a1_1:.*]]: {{.*}})
230 subroutine ref_scalar_def_char_a(a0_0, a1_0, a0_1, a1_1)
231 type(def_char_a0) :: a0_0, a0_1(100)
232 type(def_char_a1) :: a1_0, a1_1(100)
234 ! CHECK: %[[fld:.*]] = fir.field_index p
235 ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[a0_0]], %[[fld]]
236 ! CHECK: %[[box:.*]] = fir.load %[[coor]]
237 ! CHECK-DAG: %[[len:.*]] = fir.box_elesize %[[box]]
238 ! CHECK-DAG: %[[addr:.*]] = fir.box_addr %[[box]]
239 ! CHECK-DAG: %[[cast:.*]] = fir.convert %[[addr]]
240 ! CHECK: %[[boxchar:.*]] = fir.emboxchar %[[cast]], %[[len]]
241 ! CHECK: fir.call @_QPtakes_char_scalar(%[[boxchar]])
242 call takes_char_scalar(a0_0%p)
244 ! CHECK-DAG: %[[coor0:.*]] = fir.coordinate_of %[[a0_1]], %{{.*}}
245 ! CHECK-DAG: %[[fld:.*]] = fir.field_index p
246 ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[coor0]], %[[fld]]
247 ! CHECK: %[[box:.*]] = fir.load %[[coor]]
248 ! CHECK-DAG: %[[len:.*]] = fir.box_elesize %[[box]]
249 ! CHECK-DAG: %[[addr:.*]] = fir.box_addr %[[box]]
250 ! CHECK-DAG: %[[cast:.*]] = fir.convert %[[addr]]
251 ! CHECK: %[[boxchar:.*]] = fir.emboxchar %[[cast]], %[[len]]
252 ! CHECK: fir.call @_QPtakes_char_scalar(%[[boxchar]])
253 call takes_char_scalar(a0_1(5)%p)
256 ! CHECK-DAG: %[[fld:.*]] = fir.field_index p
257 ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[a1_0]], %[[fld]]
258 ! CHECK: %[[box:.*]] = fir.load %[[coor]]
259 ! CHECK-DAG: %[[dims:.*]]:3 = fir.box_dims %[[box]], %c0{{.*}}
260 ! CHECK-DAG: %[[len:.*]] = fir.box_elesize %[[box]]
261 ! CHECK-DAG: %[[base:.*]] = fir.box_addr %[[box]]
262 ! CHECK: %[[cast:.*]] = fir.convert %[[base]] : (!fir.heap<!fir.array<?x!fir.char<1,?>>>) -> !fir.ref<!fir.array<?x!fir.char<1,?>>>
263 ! CHECK: %[[c7:.*]] = fir.convert %c7{{.*}} : (i64) -> index
264 ! CHECK: %[[sub:.*]] = arith.subi %[[c7]], %[[dims]]#0 : index
265 ! CHECK: %[[mul:.*]] = arith.muli %[[len]], %[[sub]] : index
266 ! CHECK: %[[offset:.*]] = arith.addi %[[mul]], %c0{{.*}} : index
267 ! CHECK: %[[cnvt:.*]] = fir.convert %[[cast]]
268 ! CHECK: %[[addr:.*]] = fir.coordinate_of %[[cnvt]], %[[offset]]
269 ! CHECK: %[[cnvt:.*]] = fir.convert %[[addr]]
270 ! CHECK: %[[boxchar:.*]] = fir.emboxchar %[[cnvt]], %[[len]]
271 ! CHECK: fir.call @_QPtakes_char_scalar(%[[boxchar]])
272 call takes_char_scalar(a1_0%p(7))
275 ! CHECK-DAG: %[[coor0:.*]] = fir.coordinate_of %[[a1_1]], %{{.*}}
276 ! CHECK-DAG: %[[fld:.*]] = fir.field_index p
277 ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[coor0]], %[[fld]]
278 ! CHECK: %[[box:.*]] = fir.load %[[coor]]
279 ! CHECK-DAG: %[[dims:.*]]:3 = fir.box_dims %[[box]], %c0{{.*}}
280 ! CHECK-DAG: %[[len:.*]] = fir.box_elesize %[[box]]
281 ! CHECK-DAG: %[[base:.*]] = fir.box_addr %[[box]]
282 ! CHECK: %[[cast:.*]] = fir.convert %[[base]] : (!fir.heap<!fir.array<?x!fir.char<1,?>>>) -> !fir.ref<!fir.array<?x!fir.char<1,?>>>
283 ! CHECK: %[[c7:.*]] = fir.convert %c7{{.*}} : (i64) -> index
284 ! CHECK: %[[sub:.*]] = arith.subi %[[c7]], %[[dims]]#0 : index
285 ! CHECK: %[[mul:.*]] = arith.muli %[[len]], %[[sub]] : index
286 ! CHECK: %[[offset:.*]] = arith.addi %[[mul]], %c0{{.*}} : index
287 ! CHECK: %[[cnvt:.*]] = fir.convert %[[cast]]
288 ! CHECK: %[[addr:.*]] = fir.coordinate_of %[[cnvt]], %[[offset]]
289 ! CHECK: %[[cnvt:.*]] = fir.convert %[[addr]]
290 ! CHECK: %[[boxchar:.*]] = fir.emboxchar %[[cnvt]], %[[len]]
291 ! CHECK: fir.call @_QPtakes_char_scalar(%[[boxchar]])
292 call takes_char_scalar(a1_1(5)%p(7))
294 end subroutine
296 ! CHECK-LABEL: func @_QMacompPref_scalar_derived
297 ! CHECK-SAME: (%[[a0_0:.*]]: {{.*}}, %[[a1_0:.*]]: {{.*}}, %[[a0_1:.*]]: {{.*}}, %[[a1_1:.*]]: {{.*}})
298 subroutine ref_scalar_derived(a0_0, a1_0, a0_1, a1_1)
299 type(derived_a0) :: a0_0, a0_1(100)
300 type(derived_a1) :: a1_0, a1_1(100)
302 ! CHECK: %[[fld:.*]] = fir.field_index p
303 ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[a0_0]], %[[fld]]
304 ! CHECK: %[[box:.*]] = fir.load %[[coor]]
305 ! CHECK: %[[fldx:.*]] = fir.field_index x
306 ! CHECK: %[[addr:.*]] = fir.coordinate_of %[[box]], %[[fldx]]
307 ! CHECK: fir.call @_QPtakes_real_scalar(%[[addr]])
308 call takes_real_scalar(a0_0%p%x)
310 ! CHECK-DAG: %[[coor0:.*]] = fir.coordinate_of %[[a0_1]], %{{.*}}
311 ! CHECK-DAG: %[[fld:.*]] = fir.field_index p
312 ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[coor0]], %[[fld]]
313 ! CHECK: %[[box:.*]] = fir.load %[[coor]]
314 ! CHECK: %[[fldx:.*]] = fir.field_index x
315 ! CHECK: %[[addr:.*]] = fir.coordinate_of %[[box]], %[[fldx]]
316 ! CHECK: fir.call @_QPtakes_real_scalar(%[[addr]])
317 call takes_real_scalar(a0_1(5)%p%x)
319 ! CHECK: %[[fld:.*]] = fir.field_index p
320 ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[a1_0]], %[[fld]]
321 ! CHECK: %[[box:.*]] = fir.load %[[coor]]
322 ! CHECK: %[[dims:.*]]:3 = fir.box_dims %[[box]], %c0{{.*}}
323 ! CHECK: %[[lb:.*]] = fir.convert %[[dims]]#0 : (index) -> i64
324 ! CHECK: %[[index:.*]] = arith.subi %c7{{.*}}, %[[lb]] : i64
325 ! CHECK: %[[elem:.*]] = fir.coordinate_of %[[box]], %[[index]]
326 ! CHECK: %[[fldx:.*]] = fir.field_index x
327 ! CHECK: %[[addr:.*]] = fir.coordinate_of %[[elem]], %[[fldx]]
328 ! CHECK: fir.call @_QPtakes_real_scalar(%[[addr]])
329 call takes_real_scalar(a1_0%p(7)%x)
331 ! CHECK-DAG: %[[coor0:.*]] = fir.coordinate_of %[[a1_1]], %{{.*}}
332 ! CHECK-DAG: %[[fld:.*]] = fir.field_index p
333 ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[coor0]], %[[fld]]
334 ! CHECK: %[[box:.*]] = fir.load %[[coor]]
335 ! CHECK: %[[dims:.*]]:3 = fir.box_dims %[[box]], %c0{{.*}}
336 ! CHECK: %[[lb:.*]] = fir.convert %[[dims]]#0 : (index) -> i64
337 ! CHECK: %[[index:.*]] = arith.subi %c7{{.*}}, %[[lb]] : i64
338 ! CHECK: %[[elem:.*]] = fir.coordinate_of %[[box]], %[[index]]
339 ! CHECK: %[[fldx:.*]] = fir.field_index x
340 ! CHECK: %[[addr:.*]] = fir.coordinate_of %[[elem]], %[[fldx]]
341 ! CHECK: fir.call @_QPtakes_real_scalar(%[[addr]])
342 call takes_real_scalar(a1_1(5)%p(7)%x)
344 end subroutine
346 ! -----------------------------------------------------------------------------
347 ! Test passing allocatable component references as allocatables
348 ! -----------------------------------------------------------------------------
350 ! CHECK-LABEL: func @_QMacompPpass_real_a
351 ! CHECK-SAME: (%[[a0_0:.*]]: {{.*}}, %[[a1_0:.*]]: {{.*}}, %[[a0_1:.*]]: {{.*}}, %[[a1_1:.*]]: {{.*}})
352 subroutine pass_real_a(a0_0, a1_0, a0_1, a1_1)
353 type(real_a0) :: a0_0, a0_1(100)
354 type(real_a1) :: a1_0, a1_1(100)
355 ! CHECK: %[[fld:.*]] = fir.field_index p
356 ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[a0_0]], %[[fld]]
357 ! CHECK: fir.call @_QPtakes_real_scalar_pointer(%[[coor]])
358 call takes_real_scalar_pointer(a0_0%p)
360 ! CHECK-DAG: %[[coor0:.*]] = fir.coordinate_of %[[a0_1]], %{{.*}}
361 ! CHECK-DAG: %[[fld:.*]] = fir.field_index p
362 ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[coor0]], %[[fld]]
363 ! CHECK: fir.call @_QPtakes_real_scalar_pointer(%[[coor]])
364 call takes_real_scalar_pointer(a0_1(5)%p)
366 ! CHECK: %[[fld:.*]] = fir.field_index p
367 ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[a1_0]], %[[fld]]
368 ! CHECK: fir.call @_QPtakes_real_array_pointer(%[[coor]])
369 call takes_real_array_pointer(a1_0%p)
371 ! CHECK-DAG: %[[coor0:.*]] = fir.coordinate_of %[[a1_1]], %{{.*}}
372 ! CHECK-DAG: %[[fld:.*]] = fir.field_index p
373 ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[coor0]], %[[fld]]
374 ! CHECK: fir.call @_QPtakes_real_array_pointer(%[[coor]])
375 call takes_real_array_pointer(a1_1(5)%p)
376 end subroutine
378 ! -----------------------------------------------------------------------------
379 ! Test usage in intrinsics where pointer aspect matters
380 ! -----------------------------------------------------------------------------
382 ! CHECK-LABEL: func @_QMacompPallocated_p
383 ! CHECK-SAME: (%[[a0_0:.*]]: {{.*}}, %[[a1_0:.*]]: {{.*}}, %[[a0_1:.*]]: {{.*}}, %[[a1_1:.*]]: {{.*}})
384 subroutine allocated_p(a0_0, a1_0, a0_1, a1_1)
385 type(real_a0) :: a0_0, a0_1(100)
386 type(def_char_a1) :: a1_0, a1_1(100)
387 ! CHECK: %[[fld:.*]] = fir.field_index p
388 ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[a0_0]], %[[fld]]
389 ! CHECK: %[[box:.*]] = fir.load %[[coor]]
390 ! CHECK: fir.box_addr %[[box]]
391 call takes_logical(allocated(a0_0%p))
393 ! CHECK-DAG: %[[coor0:.*]] = fir.coordinate_of %[[a0_1]], %{{.*}}
394 ! CHECK-DAG: %[[fld:.*]] = fir.field_index p
395 ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[coor0]], %[[fld]]
396 ! CHECK: %[[box:.*]] = fir.load %[[coor]]
397 ! CHECK: fir.box_addr %[[box]]
398 call takes_logical(allocated(a0_1(5)%p))
400 ! CHECK: %[[fld:.*]] = fir.field_index p
401 ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[a1_0]], %[[fld]]
402 ! CHECK: %[[box:.*]] = fir.load %[[coor]]
403 ! CHECK: fir.box_addr %[[box]]
404 call takes_logical(allocated(a1_0%p))
406 ! CHECK-DAG: %[[coor0:.*]] = fir.coordinate_of %[[a1_1]], %{{.*}}
407 ! CHECK-DAG: %[[fld:.*]] = fir.field_index p
408 ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[coor0]], %[[fld]]
409 ! CHECK: %[[box:.*]] = fir.load %[[coor]]
410 ! CHECK: fir.box_addr %[[box]]
411 call takes_logical(allocated(a1_1(5)%p))
412 end subroutine
414 ! -----------------------------------------------------------------------------
415 ! Test allocation
416 ! -----------------------------------------------------------------------------
418 ! CHECK-LABEL: func @_QMacompPallocate_real
419 ! CHECK-SAME: (%[[a0_0:.*]]: {{.*}}, %[[a1_0:.*]]: {{.*}}, %[[a0_1:.*]]: {{.*}}, %[[a1_1:.*]]: {{.*}})
420 subroutine allocate_real(a0_0, a1_0, a0_1, a1_1)
421 type(real_a0) :: a0_0, a0_1(100)
422 type(real_a1) :: a1_0, a1_1(100)
423 ! CHECK: %[[fld:.*]] = fir.field_index p
424 ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[a0_0]], %[[fld]]
425 ! CHECK: fir.store {{.*}} to %[[coor]]
426 allocate(a0_0%p)
428 ! CHECK-DAG: %[[coor0:.*]] = fir.coordinate_of %[[a0_1]], %{{.*}}
429 ! CHECK-DAG: %[[fld:.*]] = fir.field_index p
430 ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[coor0]], %[[fld]]
431 ! CHECK: fir.store {{.*}} to %[[coor]]
432 allocate(a0_1(5)%p)
434 ! CHECK: %[[fld:.*]] = fir.field_index p
435 ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[a1_0]], %[[fld]]
436 ! CHECK: fir.store {{.*}} to %[[coor]]
437 allocate(a1_0%p(100))
439 ! CHECK-DAG: %[[coor0:.*]] = fir.coordinate_of %[[a1_1]], %{{.*}}
440 ! CHECK-DAG: %[[fld:.*]] = fir.field_index p
441 ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[coor0]], %[[fld]]
442 ! CHECK: fir.store {{.*}} to %[[coor]]
443 allocate(a1_1(5)%p(100))
444 end subroutine
446 ! CHECK-LABEL: func @_QMacompPallocate_cst_char
447 ! CHECK-SAME: (%[[a0_0:.*]]: {{.*}}, %[[a1_0:.*]]: {{.*}}, %[[a0_1:.*]]: {{.*}}, %[[a1_1:.*]]: {{.*}})
448 subroutine allocate_cst_char(a0_0, a1_0, a0_1, a1_1)
449 type(cst_char_a0) :: a0_0, a0_1(100)
450 type(cst_char_a1) :: a1_0, a1_1(100)
451 ! CHECK: %[[fld:.*]] = fir.field_index p
452 ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[a0_0]], %[[fld]]
453 ! CHECK: fir.store {{.*}} to %[[coor]]
454 allocate(a0_0%p)
456 ! CHECK-DAG: %[[coor0:.*]] = fir.coordinate_of %[[a0_1]], %{{.*}}
457 ! CHECK-DAG: %[[fld:.*]] = fir.field_index p
458 ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[coor0]], %[[fld]]
459 ! CHECK: fir.store {{.*}} to %[[coor]]
460 allocate(a0_1(5)%p)
462 ! CHECK: %[[fld:.*]] = fir.field_index p
463 ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[a1_0]], %[[fld]]
464 ! CHECK: fir.store {{.*}} to %[[coor]]
465 allocate(a1_0%p(100))
467 ! CHECK-DAG: %[[coor0:.*]] = fir.coordinate_of %[[a1_1]], %{{.*}}
468 ! CHECK-DAG: %[[fld:.*]] = fir.field_index p
469 ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[coor0]], %[[fld]]
470 ! CHECK: fir.store {{.*}} to %[[coor]]
471 allocate(a1_1(5)%p(100))
472 end subroutine
474 ! CHECK-LABEL: func @_QMacompPallocate_def_char
475 ! CHECK-SAME: (%[[a0_0:.*]]: {{.*}}, %[[a1_0:.*]]: {{.*}}, %[[a0_1:.*]]: {{.*}}, %[[a1_1:.*]]: {{.*}})
476 subroutine allocate_def_char(a0_0, a1_0, a0_1, a1_1)
477 type(def_char_a0) :: a0_0, a0_1(100)
478 type(def_char_a1) :: a1_0, a1_1(100)
479 ! CHECK: %[[fld:.*]] = fir.field_index p
480 ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[a0_0]], %[[fld]]
481 ! CHECK: fir.store {{.*}} to %[[coor]]
482 allocate(character(18)::a0_0%p)
484 ! CHECK-DAG: %[[coor0:.*]] = fir.coordinate_of %[[a0_1]], %{{.*}}
485 ! CHECK-DAG: %[[fld:.*]] = fir.field_index p
486 ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[coor0]], %[[fld]]
487 ! CHECK: fir.store {{.*}} to %[[coor]]
488 allocate(character(18)::a0_1(5)%p)
490 ! CHECK: %[[fld:.*]] = fir.field_index p
491 ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[a1_0]], %[[fld]]
492 ! CHECK: fir.store {{.*}} to %[[coor]]
493 allocate(character(18)::a1_0%p(100))
495 ! CHECK-DAG: %[[coor0:.*]] = fir.coordinate_of %[[a1_1]], %{{.*}}
496 ! CHECK-DAG: %[[fld:.*]] = fir.field_index p
497 ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[coor0]], %[[fld]]
498 ! CHECK: fir.store {{.*}} to %[[coor]]
499 allocate(character(18)::a1_1(5)%p(100))
500 end subroutine
502 ! -----------------------------------------------------------------------------
503 ! Test deallocation
504 ! -----------------------------------------------------------------------------
506 ! CHECK-LABEL: func @_QMacompPdeallocate_real
507 ! CHECK-SAME: (%[[a0_0:.*]]: {{.*}}, %[[a1_0:.*]]: {{.*}}, %[[a0_1:.*]]: {{.*}}, %[[a1_1:.*]]: {{.*}})
508 subroutine deallocate_real(a0_0, a1_0, a0_1, a1_1)
509 type(real_a0) :: a0_0, a0_1(100)
510 type(real_a1) :: a1_0, a1_1(100)
511 ! CHECK: %[[fld:.*]] = fir.field_index p
512 ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[a0_0]], %[[fld]]
513 ! CHECK: fir.store {{.*}} to %[[coor]]
514 deallocate(a0_0%p)
516 ! CHECK-DAG: %[[coor0:.*]] = fir.coordinate_of %[[a0_1]], %{{.*}}
517 ! CHECK-DAG: %[[fld:.*]] = fir.field_index p
518 ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[coor0]], %[[fld]]
519 ! CHECK: fir.store {{.*}} to %[[coor]]
520 deallocate(a0_1(5)%p)
522 ! CHECK: %[[fld:.*]] = fir.field_index p
523 ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[a1_0]], %[[fld]]
524 ! CHECK: fir.store {{.*}} to %[[coor]]
525 deallocate(a1_0%p)
527 ! CHECK-DAG: %[[coor0:.*]] = fir.coordinate_of %[[a1_1]], %{{.*}}
528 ! CHECK-DAG: %[[fld:.*]] = fir.field_index p
529 ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[coor0]], %[[fld]]
530 ! CHECK: fir.store {{.*}} to %[[coor]]
531 deallocate(a1_1(5)%p)
532 end subroutine
534 ! -----------------------------------------------------------------------------
535 ! Test a recursive derived type reference
536 ! -----------------------------------------------------------------------------
538 ! CHECK: func @_QMacompPtest_recursive
539 ! CHECK-SAME: (%[[x:.*]]: {{.*}})
540 subroutine test_recursive(x)
541 type t
542 integer :: i
543 type(t), allocatable :: next
544 end type
545 type(t) :: x
547 ! CHECK: %[[fldNext1:.*]] = fir.field_index next
548 ! CHECK: %[[next1:.*]] = fir.coordinate_of %[[x]], %[[fldNext1]]
549 ! CHECK: %[[nextBox1:.*]] = fir.load %[[next1]]
550 ! CHECK: %[[fldNext2:.*]] = fir.field_index next
551 ! CHECK: %[[next2:.*]] = fir.coordinate_of %[[nextBox1]], %[[fldNext2]]
552 ! CHECK: %[[nextBox2:.*]] = fir.load %[[next2]]
553 ! CHECK: %[[fldNext3:.*]] = fir.field_index next
554 ! CHECK: %[[next3:.*]] = fir.coordinate_of %[[nextBox2]], %[[fldNext3]]
555 ! CHECK: %[[nextBox3:.*]] = fir.load %[[next3]]
556 ! CHECK: %[[fldi:.*]] = fir.field_index i
557 ! CHECK: %[[i:.*]] = fir.coordinate_of %[[nextBox3]], %[[fldi]]
558 ! CHECK: %[[nextBox3:.*]] = fir.load %[[i]] : !fir.ref<i32>
559 print *, x%next%next%next%i
560 end subroutine
562 end module