[flang] Accept polymorphic component element in storage_size
[llvm-project.git] / flang / test / Lower / explicit-interface-results.f90
blob7821c4041b969e27f6ec158079c814a145849745
1 ! RUN: bbc -emit-fir %s -o - | FileCheck %s
3 module callee
4 implicit none
5 contains
6 ! CHECK-LABEL: func @_QMcalleePreturn_cst_array() -> !fir.array<20x30xf32>
7 function return_cst_array()
8 real :: return_cst_array(20, 30)
9 end function
11 ! CHECK-LABEL: func @_QMcalleePreturn_dyn_array(
12 ! CHECK-SAME: %{{.*}}: !fir.ref<i32>{{.*}}, %{{.*}}: !fir.ref<i32>{{.*}}) -> !fir.array<?x?xf32>
13 function return_dyn_array(m, n)
14 integer :: m, n
15 real :: return_dyn_array(m, n)
16 end function
18 ! CHECK-LABEL: func @_QMcalleePreturn_cst_char_cst_array() -> !fir.array<20x30x!fir.char<1,10>>
19 function return_cst_char_cst_array()
20 character(10) :: return_cst_char_cst_array(20, 30)
21 end function
23 ! CHECK-LABEL: func @_QMcalleePreturn_dyn_char_cst_array(
24 ! CHECK-SAME: %{{.*}}: !fir.ref<i32>{{.*}}) -> !fir.array<20x30x!fir.char<1,?>>
25 function return_dyn_char_cst_array(l)
26 integer :: l
27 character(l) :: return_dyn_char_cst_array(20, 30)
28 end function
30 ! CHECK-LABEL: func @_QMcalleePreturn_cst_char_dyn_array(
31 ! CHECK-SAME: %{{.*}}: !fir.ref<i32>{{.*}}, %{{.*}}: !fir.ref<i32>{{.*}}) -> !fir.array<?x?x!fir.char<1,10>>
32 function return_cst_char_dyn_array(m, n)
33 integer :: m, n
34 character(10) :: return_cst_char_dyn_array(m, n)
35 end function
37 ! CHECK-LABEL: func @_QMcalleePreturn_dyn_char_dyn_array(
38 ! CHECK-SAME: %{{.*}}: !fir.ref<i32>{{.*}}, %{{.*}}: !fir.ref<i32>{{.*}}, %{{.*}}: !fir.ref<i32>{{.*}}) -> !fir.array<?x?x!fir.char<1,?>>
39 function return_dyn_char_dyn_array(l, m, n)
40 integer :: l, m, n
41 character(l) :: return_dyn_char_dyn_array(m, n)
42 end function
44 ! CHECK-LABEL: func @_QMcalleePreturn_alloc() -> !fir.box<!fir.heap<!fir.array<?xf32>>>
45 function return_alloc()
46 real, allocatable :: return_alloc(:)
47 end function
49 ! CHECK-LABEL: func @_QMcalleePreturn_cst_char_alloc() -> !fir.box<!fir.heap<!fir.array<?x!fir.char<1,10>>>>
50 function return_cst_char_alloc()
51 character(10), allocatable :: return_cst_char_alloc(:)
52 end function
54 ! CHECK-LABEL: func @_QMcalleePreturn_dyn_char_alloc(
55 ! CHECK-SAME: %{{.*}}: !fir.ref<i32>{{.*}}) -> !fir.box<!fir.heap<!fir.array<?x!fir.char<1,?>>>>
56 function return_dyn_char_alloc(l)
57 integer :: l
58 character(l), allocatable :: return_dyn_char_alloc(:)
59 end function
61 ! CHECK-LABEL: func @_QMcalleePreturn_def_char_alloc() -> !fir.box<!fir.heap<!fir.array<?x!fir.char<1,?>>>>
62 function return_def_char_alloc()
63 character(:), allocatable :: return_def_char_alloc(:)
64 end function
66 ! CHECK-LABEL: func @_QMcalleePreturn_pointer() -> !fir.box<!fir.ptr<!fir.array<?xf32>>>
67 function return_pointer()
68 real, pointer :: return_pointer(:)
69 end function
71 ! CHECK-LABEL: func @_QMcalleePreturn_cst_char_pointer() -> !fir.box<!fir.ptr<!fir.array<?x!fir.char<1,10>>>>
72 function return_cst_char_pointer()
73 character(10), pointer :: return_cst_char_pointer(:)
74 end function
76 ! CHECK-LABEL: func @_QMcalleePreturn_dyn_char_pointer(
77 ! CHECK-SAME: %{{.*}}: !fir.ref<i32>{{.*}}) -> !fir.box<!fir.ptr<!fir.array<?x!fir.char<1,?>>>>
78 function return_dyn_char_pointer(l)
79 integer :: l
80 character(l), pointer :: return_dyn_char_pointer(:)
81 end function
83 ! CHECK-LABEL: func @_QMcalleePreturn_def_char_pointer() -> !fir.box<!fir.ptr<!fir.array<?x!fir.char<1,?>>>>
84 function return_def_char_pointer()
85 character(:), pointer :: return_def_char_pointer(:)
86 end function
87 end module
89 module caller
90 use callee
91 contains
93 ! CHECK-LABEL: func @_QMcallerPcst_array()
94 subroutine cst_array()
95 ! CHECK: %[[alloc:.*]] = fir.alloca !fir.array<20x30xf32> {{{.*}}bindc_name = ".result"}
96 ! CHECK: %[[shape:.*]] = fir.shape %{{.*}}, {{.*}} : (index, index) -> !fir.shape<2>
97 ! CHECK: %[[res:.*]] = fir.call @_QMcalleePreturn_cst_array() {{.*}}: () -> !fir.array<20x30xf32>
98 ! CHECK: fir.save_result %[[res]] to %[[alloc]](%[[shape]]) : !fir.array<20x30xf32>, !fir.ref<!fir.array<20x30xf32>>, !fir.shape<2>
99 print *, return_cst_array()
100 end subroutine
102 ! CHECK-LABEL: func @_QMcallerPcst_char_cst_array()
103 subroutine cst_char_cst_array()
104 ! CHECK: %[[alloc:.*]] = fir.alloca !fir.array<20x30x!fir.char<1,10>> {{{.*}}bindc_name = ".result"}
105 ! CHECK: %[[shape:.*]] = fir.shape %{{.*}}, {{.*}} : (index, index) -> !fir.shape<2>
106 ! CHECK: %[[res:.*]] = fir.call @_QMcalleePreturn_cst_char_cst_array() {{.*}}: () -> !fir.array<20x30x!fir.char<1,10>>
107 ! CHECK: fir.save_result %[[res]] to %[[alloc]](%[[shape]]) typeparams %{{.*}} : !fir.array<20x30x!fir.char<1,10>>, !fir.ref<!fir.array<20x30x!fir.char<1,10>>>, !fir.shape<2>, index
108 print *, return_cst_char_cst_array()
109 end subroutine
111 ! CHECK-LABEL: func @_QMcallerPalloc()
112 subroutine alloc()
113 ! CHECK: %[[alloc:.*]] = fir.alloca !fir.box<!fir.heap<!fir.array<?xf32>>> {{{.*}}bindc_name = ".result"}
114 ! CHECK: %[[res:.*]] = fir.call @_QMcalleePreturn_alloc() {{.*}}: () -> !fir.box<!fir.heap<!fir.array<?xf32>>>
115 ! CHECK: fir.save_result %[[res]] to %[[alloc]] : !fir.box<!fir.heap<!fir.array<?xf32>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
116 print *, return_alloc()
117 ! CHECK: _FortranAioOutputDescriptor
118 ! CHECK: %[[load:.*]] = fir.load %[[alloc]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
119 ! CHECK: %[[addr:.*]] = fir.box_addr %[[load]] : (!fir.box<!fir.heap<!fir.array<?xf32>>>) -> !fir.heap<!fir.array<?xf32>>
120 ! CHECK: %[[cmpi:.*]] = arith.cmpi
121 ! CHECK: fir.if %[[cmpi]]
122 ! CHECK: fir.freemem %[[addr]] : !fir.heap<!fir.array<?xf32>>
123 end subroutine
125 ! CHECK-LABEL: func @_QMcallerPcst_char_alloc()
126 subroutine cst_char_alloc()
127 ! CHECK: %[[alloc:.*]] = fir.alloca !fir.box<!fir.heap<!fir.array<?x!fir.char<1,10>>>> {{{.*}}bindc_name = ".result"}
128 ! CHECK: %[[res:.*]] = fir.call @_QMcalleePreturn_cst_char_alloc() {{.*}}: () -> !fir.box<!fir.heap<!fir.array<?x!fir.char<1,10>>>>
129 ! CHECK: fir.save_result %[[res]] to %[[alloc]] : !fir.box<!fir.heap<!fir.array<?x!fir.char<1,10>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.char<1,10>>>>>
130 print *, return_cst_char_alloc()
131 ! CHECK: _FortranAioOutputDescriptor
132 ! CHECK: %[[load:.*]] = fir.load %[[alloc]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.char<1,10>>>>>
133 ! CHECK: %[[addr:.*]] = fir.box_addr %[[load]] : (!fir.box<!fir.heap<!fir.array<?x!fir.char<1,10>>>>) -> !fir.heap<!fir.array<?x!fir.char<1,10>>>
134 ! CHECK: %[[cmpi:.*]] = arith.cmpi
135 ! CHECK: fir.if %[[cmpi]]
136 ! CHECK: fir.freemem %[[addr]] : !fir.heap<!fir.array<?x!fir.char<1,10>>>
137 end subroutine
139 ! CHECK-LABEL: func @_QMcallerPdef_char_alloc()
140 subroutine def_char_alloc()
141 ! CHECK: %[[alloc:.*]] = fir.alloca !fir.box<!fir.heap<!fir.array<?x!fir.char<1,?>>>> {{{.*}}bindc_name = ".result"}
142 ! CHECK: %[[res:.*]] = fir.call @_QMcalleePreturn_def_char_alloc() {{.*}}: () -> !fir.box<!fir.heap<!fir.array<?x!fir.char<1,?>>>>
143 ! CHECK: fir.save_result %[[res]] to %[[alloc]] : !fir.box<!fir.heap<!fir.array<?x!fir.char<1,?>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.char<1,?>>>>>
144 print *, return_def_char_alloc()
145 ! CHECK: _FortranAioOutputDescriptor
146 ! CHECK: %[[load:.*]] = fir.load %[[alloc]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.char<1,?>>>>>
147 ! CHECK: %[[addr:.*]] = fir.box_addr %[[load]] : (!fir.box<!fir.heap<!fir.array<?x!fir.char<1,?>>>>) -> !fir.heap<!fir.array<?x!fir.char<1,?>>>
148 ! CHECK: %[[cmpi:.*]] = arith.cmpi
149 ! CHECK: fir.if %[[cmpi]]
150 ! CHECK: fir.freemem %[[addr]] : !fir.heap<!fir.array<?x!fir.char<1,?>>>
151 end subroutine
153 ! CHECK-LABEL: func @_QMcallerPpointer_test()
154 subroutine pointer_test()
155 ! CHECK: %[[alloc:.*]] = fir.alloca !fir.box<!fir.ptr<!fir.array<?xf32>>> {{{.*}}bindc_name = ".result"}
156 ! CHECK: %[[res:.*]] = fir.call @_QMcalleePreturn_pointer() {{.*}}: () -> !fir.box<!fir.ptr<!fir.array<?xf32>>>
157 ! CHECK: fir.save_result %[[res]] to %[[alloc]] : !fir.box<!fir.ptr<!fir.array<?xf32>>>, !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>
158 print *, return_pointer()
159 ! CHECK-NOT: fir.freemem
160 end subroutine
162 ! CHECK-LABEL: func @_QMcallerPcst_char_pointer()
163 subroutine cst_char_pointer()
164 ! CHECK: %[[alloc:.*]] = fir.alloca !fir.box<!fir.ptr<!fir.array<?x!fir.char<1,10>>>> {{{.*}}bindc_name = ".result"}
165 ! CHECK: %[[res:.*]] = fir.call @_QMcalleePreturn_cst_char_pointer() {{.*}}: () -> !fir.box<!fir.ptr<!fir.array<?x!fir.char<1,10>>>>
166 ! CHECK: fir.save_result %[[res]] to %[[alloc]] : !fir.box<!fir.ptr<!fir.array<?x!fir.char<1,10>>>>, !fir.ref<!fir.box<!fir.ptr<!fir.array<?x!fir.char<1,10>>>>>
167 print *, return_cst_char_pointer()
168 ! CHECK-NOT: fir.freemem
169 end subroutine
171 ! CHECK-LABEL: func @_QMcallerPdef_char_pointer()
172 subroutine def_char_pointer()
173 ! CHECK: %[[alloc:.*]] = fir.alloca !fir.box<!fir.ptr<!fir.array<?x!fir.char<1,?>>>> {{{.*}}bindc_name = ".result"}
174 ! CHECK: %[[res:.*]] = fir.call @_QMcalleePreturn_def_char_pointer() {{.*}}: () -> !fir.box<!fir.ptr<!fir.array<?x!fir.char<1,?>>>>
175 ! CHECK: fir.save_result %[[res]] to %[[alloc]] : !fir.box<!fir.ptr<!fir.array<?x!fir.char<1,?>>>>, !fir.ref<!fir.box<!fir.ptr<!fir.array<?x!fir.char<1,?>>>>>
176 print *, return_def_char_pointer()
177 ! CHECK-NOT: fir.freemem
178 end subroutine
180 ! CHECK-LABEL: func @_QMcallerPdyn_array(
181 ! CHECK-SAME: %[[m:.*]]: !fir.ref<i32>{{.*}}, %[[n:.*]]: !fir.ref<i32>{{.*}}) {
182 subroutine dyn_array(m, n)
183 integer :: m, n
184 ! CHECK-DAG: %[[mload:.*]] = fir.load %[[m]] : !fir.ref<i32>
185 ! CHECK-DAG: %[[mcast:.*]] = fir.convert %[[mload]] : (i32) -> i64
186 ! CHECK-DAG: %[[msub:.*]] = arith.subi %[[mcast]], %c1{{.*}} : i64
187 ! CHECK-DAG: %[[madd:.*]] = arith.addi %[[msub]], %c1{{.*}} : i64
188 ! CHECK-DAG: %[[mcast2:.*]] = fir.convert %[[madd]] : (i64) -> index
189 ! CHECK-DAG: %[[mcmpi:.*]] = arith.cmpi sgt, %[[mcast2]], %{{.*}} : index
190 ! CHECK-DAG: %[[mselect:.*]] = arith.select %[[mcmpi]], %[[mcast2]], %{{.*}} : index
191 ! CHECK-DAG: %[[nload:.*]] = fir.load %[[n]] : !fir.ref<i32>
192 ! CHECK-DAG: %[[ncast:.*]] = fir.convert %[[nload]] : (i32) -> i64
193 ! CHECK-DAG: %[[nsub:.*]] = arith.subi %[[ncast]], %c1{{.*}} : i64
194 ! CHECK-DAG: %[[nadd:.*]] = arith.addi %[[nsub]], %c1{{.*}} : i64
195 ! CHECK-DAG: %[[ncast2:.*]] = fir.convert %[[nadd]] : (i64) -> index
196 ! CHECK-DAG: %[[ncmpi:.*]] = arith.cmpi sgt, %[[ncast2]], %{{.*}} : index
197 ! CHECK-DAG: %[[nselect:.*]] = arith.select %[[ncmpi]], %[[ncast2]], %{{.*}} : index
198 ! CHECK: %[[tmp:.*]] = fir.alloca !fir.array<?x?xf32>, %[[mselect]], %[[nselect]]
199 ! CHECK: %[[shape:.*]] = fir.shape %[[mselect]], %[[nselect]] : (index, index) -> !fir.shape<2>
200 ! CHECK: %[[res:.*]] = fir.call @_QMcalleePreturn_dyn_array(%[[m]], %[[n]]) {{.*}}: (!fir.ref<i32>, !fir.ref<i32>) -> !fir.array<?x?xf32>
201 ! CHECK: fir.save_result %[[res]] to %[[tmp]](%[[shape]]) : !fir.array<?x?xf32>, !fir.ref<!fir.array<?x?xf32>>, !fir.shape<2>
202 print *, return_dyn_array(m, n)
203 end subroutine
205 ! CHECK-LABEL: func @_QMcallerPdyn_char_cst_array(
206 ! CHECK-SAME: %[[l:.*]]: !fir.ref<i32>{{.*}}) {
207 subroutine dyn_char_cst_array(l)
208 integer :: l
209 ! CHECK: %[[lload:.*]] = fir.load %[[l]] : !fir.ref<i32>
210 ! CHECK: %[[lcast:.*]] = fir.convert %[[lload]] : (i32) -> i64
211 ! CHECK: %[[lcast2:.*]] = fir.convert %[[lcast]] : (i64) -> index
212 ! CHECK: %[[cmpi:.*]] = arith.cmpi sgt, %[[lcast2]], %{{.*}} : index
213 ! CHECK: %[[select:.*]] = arith.select %[[cmpi]], %[[lcast2]], %{{.*}} : index
214 ! CHECK: %[[tmp:.*]] = fir.alloca !fir.array<20x30x!fir.char<1,?>>(%[[select]] : index)
215 ! CHECK: %[[shape:.*]] = fir.shape %{{.*}}, %{{.*}} : (index, index) -> !fir.shape<2>
216 ! CHECK: %[[res:.*]] = fir.call @_QMcalleePreturn_dyn_char_cst_array(%[[l]]) {{.*}}: (!fir.ref<i32>) -> !fir.array<20x30x!fir.char<1,?>>
217 ! CHECK: fir.save_result %[[res]] to %[[tmp]](%[[shape]]) typeparams %[[select]] : !fir.array<20x30x!fir.char<1,?>>, !fir.ref<!fir.array<20x30x!fir.char<1,?>>>, !fir.shape<2>, index
218 print *, return_dyn_char_cst_array(l)
219 end subroutine
221 ! CHECK-LABEL: func @_QMcallerPcst_char_dyn_array(
222 ! CHECK-SAME: %[[m:.*]]: !fir.ref<i32>{{.*}}, %[[n:.*]]: !fir.ref<i32>{{.*}}) {
223 subroutine cst_char_dyn_array(m, n)
224 integer :: m, n
225 ! CHECK-DAG: %[[mload:.*]] = fir.load %[[m]] : !fir.ref<i32>
226 ! CHECK-DAG: %[[mcast:.*]] = fir.convert %[[mload]] : (i32) -> i64
227 ! CHECK-DAG: %[[msub:.*]] = arith.subi %[[mcast]], %c1{{.*}} : i64
228 ! CHECK-DAG: %[[madd:.*]] = arith.addi %[[msub]], %c1{{.*}} : i64
229 ! CHECK-DAG: %[[mcast2:.*]] = fir.convert %[[madd]] : (i64) -> index
230 ! CHECK-DAG: %[[mcmpi:.*]] = arith.cmpi sgt, %[[mcast2]], %{{.*}} : index
231 ! CHECK-DAG: %[[mselect:.*]] = arith.select %[[mcmpi]], %[[mcast2]], %{{.*}} : index
232 ! CHECK-DAG: %[[nload:.*]] = fir.load %[[n]] : !fir.ref<i32>
233 ! CHECK-DAG: %[[ncast:.*]] = fir.convert %[[nload]] : (i32) -> i64
234 ! CHECK-DAG: %[[nsub:.*]] = arith.subi %[[ncast]], %c1{{.*}} : i64
235 ! CHECK-DAG: %[[nadd:.*]] = arith.addi %[[nsub]], %c1{{.*}} : i64
236 ! CHECK-DAG: %[[ncast2:.*]] = fir.convert %[[nadd]] : (i64) -> index
237 ! CHECK-DAG: %[[ncmpi:.*]] = arith.cmpi sgt, %[[ncast2]], %{{.*}} : index
238 ! CHECK-DAG: %[[nselect:.*]] = arith.select %[[ncmpi]], %[[ncast2]], %{{.*}} : index
239 ! CHECK: %[[tmp:.*]] = fir.alloca !fir.array<?x?x!fir.char<1,10>>, %[[mselect]], %[[nselect]]
240 ! CHECK: %[[shape:.*]] = fir.shape %[[mselect]], %[[nselect]] : (index, index) -> !fir.shape<2>
241 ! CHECK: %[[res:.*]] = fir.call @_QMcalleePreturn_cst_char_dyn_array(%[[m]], %[[n]]) {{.*}}: (!fir.ref<i32>, !fir.ref<i32>) -> !fir.array<?x?x!fir.char<1,10>>
242 ! CHECK: fir.save_result %[[res]] to %[[tmp]](%[[shape]]) typeparams {{.*}} : !fir.array<?x?x!fir.char<1,10>>, !fir.ref<!fir.array<?x?x!fir.char<1,10>>>, !fir.shape<2>, index
243 print *, return_cst_char_dyn_array(m, n)
244 end subroutine
246 ! CHECK-LABEL: func @_QMcallerPdyn_char_dyn_array(
247 ! CHECK-SAME: %[[l:.*]]: !fir.ref<i32>{{.*}}, %[[m:.*]]: !fir.ref<i32>{{.*}}, %[[n:.*]]: !fir.ref<i32>{{.*}}) {
248 subroutine dyn_char_dyn_array(l, m, n)
249 ! CHECK-DAG: %[[mload:.*]] = fir.load %[[m]] : !fir.ref<i32>
250 ! CHECK-DAG: %[[mcast:.*]] = fir.convert %[[mload]] : (i32) -> i64
251 ! CHECK-DAG: %[[msub:.*]] = arith.subi %[[mcast]], %c1{{.*}} : i64
252 ! CHECK-DAG: %[[madd:.*]] = arith.addi %[[msub]], %c1{{.*}} : i64
253 ! CHECK-DAG: %[[mcast2:.*]] = fir.convert %[[madd]] : (i64) -> index
254 ! CHECK-DAG: %[[mcmpi:.*]] = arith.cmpi sgt, %[[mcast2]], %{{.*}} : index
255 ! CHECK-DAG: %[[mselect:.*]] = arith.select %[[mcmpi]], %[[mcast2]], %{{.*}} : index
257 ! CHECK-DAG: %[[nload:.*]] = fir.load %[[n]] : !fir.ref<i32>
258 ! CHECK-DAG: %[[ncast:.*]] = fir.convert %[[nload]] : (i32) -> i64
259 ! CHECK-DAG: %[[nsub:.*]] = arith.subi %[[ncast]], %c1{{.*}} : i64
260 ! CHECK-DAG: %[[nadd:.*]] = arith.addi %[[nsub]], %c1{{.*}} : i64
261 ! CHECK-DAG: %[[ncast2:.*]] = fir.convert %[[nadd]] : (i64) -> index
262 ! CHECK-DAG: %[[ncmpi:.*]] = arith.cmpi sgt, %[[ncast2]], %{{.*}} : index
263 ! CHECK-DAG: %[[nselect:.*]] = arith.select %[[ncmpi]], %[[ncast2]], %{{.*}} : index
265 ! CHECK-DAG: %[[lload:.*]] = fir.load %[[l]] : !fir.ref<i32>
266 ! CHECK-DAG: %[[lcast:.*]] = fir.convert %[[lload]] : (i32) -> i64
267 ! CHECK-DAG: %[[lcast2:.*]] = fir.convert %[[lcast]] : (i64) -> index
268 ! CHECK-DAG: %[[lcmpi:.*]] = arith.cmpi sgt, %[[lcast2]], %{{.*}} : index
269 ! CHECK-DAG: %[[lselect:.*]] = arith.select %[[lcmpi]], %[[lcast2]], %{{.*}} : index
270 ! CHECK: %[[tmp:.*]] = fir.alloca !fir.array<?x?x!fir.char<1,?>>(%[[lselect]] : index), %[[mselect]], %[[nselect]]
271 ! CHECK: %[[shape:.*]] = fir.shape %[[mselect]], %[[nselect]] : (index, index) -> !fir.shape<2>
272 ! CHECK: %[[res:.*]] = fir.call @_QMcalleePreturn_dyn_char_dyn_array(%[[l]], %[[m]], %[[n]]) {{.*}}: (!fir.ref<i32>, !fir.ref<i32>, !fir.ref<i32>) -> !fir.array<?x?x!fir.char<1,?>>
273 ! CHECK: fir.save_result %[[res]] to %[[tmp]](%[[shape]]) typeparams {{.*}} : !fir.array<?x?x!fir.char<1,?>>, !fir.ref<!fir.array<?x?x!fir.char<1,?>>>, !fir.shape<2>, index
274 integer :: l, m, n
275 print *, return_dyn_char_dyn_array(l, m, n)
276 end subroutine
278 ! CHECK-LABEL: @_QMcallerPdyn_char_alloc
279 subroutine dyn_char_alloc(l)
280 integer :: l
281 ! CHECK: %[[alloc:.*]] = fir.alloca !fir.box<!fir.heap<!fir.array<?x!fir.char<1,?>>>> {{{.*}}bindc_name = ".result"}
282 ! CHECK: %[[res:.*]] = fir.call @_QMcalleePreturn_dyn_char_alloc({{.*}}) {{.*}}: (!fir.ref<i32>) -> !fir.box<!fir.heap<!fir.array<?x!fir.char<1,?>>>>
283 ! CHECK: fir.save_result %[[res]] to %[[alloc]] : !fir.box<!fir.heap<!fir.array<?x!fir.char<1,?>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.char<1,?>>>>>
284 print *, return_dyn_char_alloc(l)
285 ! CHECK: _FortranAioOutputDescriptor
286 ! CHECK: %[[load:.*]] = fir.load %[[alloc]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.char<1,?>>>>>
287 ! CHECK: %[[addr:.*]] = fir.box_addr %[[load]] : (!fir.box<!fir.heap<!fir.array<?x!fir.char<1,?>>>>) -> !fir.heap<!fir.array<?x!fir.char<1,?>>>
288 ! CHECK: %[[cmpi:.*]] = arith.cmpi
289 ! CHECK: fir.if %[[cmpi]]
290 ! CHECK: fir.freemem %[[addr]] : !fir.heap<!fir.array<?x!fir.char<1,?>>>
291 end subroutine
293 ! CHECK-LABEL: @_QMcallerPdyn_char_pointer
294 subroutine dyn_char_pointer(l)
295 integer :: l
296 ! CHECK: %[[alloc:.*]] = fir.alloca !fir.box<!fir.ptr<!fir.array<?x!fir.char<1,?>>>> {{{.*}}bindc_name = ".result"}
297 ! CHECK: %[[res:.*]] = fir.call @_QMcalleePreturn_dyn_char_pointer({{.*}}) {{.*}}: (!fir.ref<i32>) -> !fir.box<!fir.ptr<!fir.array<?x!fir.char<1,?>>>>
298 ! CHECK: fir.save_result %[[res]] to %[[alloc]] : !fir.box<!fir.ptr<!fir.array<?x!fir.char<1,?>>>>, !fir.ref<!fir.box<!fir.ptr<!fir.array<?x!fir.char<1,?>>>>>
299 print *, return_dyn_char_pointer(l)
300 ! CHECK-NOT: fir.freemem
301 end subroutine
303 end module
306 ! Test more complex symbol dependencies in the result specification expression
308 module m_with_equiv
309 integer(8) :: l
310 integer(8) :: array(3)
311 equivalence (array(2), l)
312 contains
313 function result_depends_on_equiv_sym()
314 character(l) :: result_depends_on_equiv_sym
315 call set_result_with_some_value(result_depends_on_equiv_sym)
316 end function
317 end module
319 ! CHECK-LABEL: func @_QPtest_result_depends_on_equiv_sym
320 subroutine test_result_depends_on_equiv_sym()
321 use m_with_equiv, only : result_depends_on_equiv_sym
322 ! CHECK: %[[equiv:.*]] = fir.address_of(@_QMm_with_equivEarray) : !fir.ref<!fir.array<24xi8>>
323 ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[equiv]], %c{{.*}} : (!fir.ref<!fir.array<24xi8>>, index) -> !fir.ref<i8>
324 ! CHECK: %[[l:.*]] = fir.convert %[[coor]] : (!fir.ref<i8>) -> !fir.ptr<i64>
325 ! CHECK: %[[load:.*]] = fir.load %[[l]] : !fir.ptr<i64>
326 ! CHECK: %[[lcast:.*]] = fir.convert %[[load]] : (i64) -> index
327 ! CHECK: %[[cmpi:.*]] = arith.cmpi sgt, %[[lcast]], %{{.*}} : index
328 ! CHECK: %[[select:.*]] = arith.select %[[cmpi]], %[[lcast]], %{{.*}} : index
329 ! CHECK: fir.alloca !fir.char<1,?>(%[[select]] : index)
330 print *, result_depends_on_equiv_sym()
331 end subroutine
333 ! CHECK-LABEL: func @_QPtest_depends_on_descriptor(
334 ! CHECK-SAME: %[[x:.*]]: !fir.box<!fir.array<?xf32>>{{.*}}) {
335 subroutine test_depends_on_descriptor(x)
336 interface
337 function depends_on_descriptor(x)
338 real :: x(:)
339 character(size(x,1, KIND=8)) :: depends_on_descriptor
340 end function
341 end interface
342 real :: x(:)
343 ! CHECK: %[[dims:.*]]:3 = fir.box_dims %arg0, %c0 : (!fir.box<!fir.array<?xf32>>, index) -> (index, index, index)
344 ! CHECK: %[[extentCast:.*]] = fir.convert %[[dims]]#1 : (index) -> i64
345 ! CHECK: %[[extent:.*]] = fir.convert %[[extentCast]] : (i64) -> index
346 ! CHECK: %[[cmpi:.*]] = arith.cmpi sgt, %[[extent]], %{{.*}} : index
347 ! CHECK: %[[select:.*]] = arith.select %[[cmpi]], %[[extent]], %{{.*}} : index
348 ! CHECK: fir.alloca !fir.char<1,?>(%[[select]] : index)
349 print *, depends_on_descriptor(x)
350 end subroutine
352 ! CHECK-LABEL: func @_QPtest_symbol_indirection(
353 ! CHECK-SAME: %[[n:.*]]: !fir.ref<i64>{{.*}}) {
354 subroutine test_symbol_indirection(n)
355 interface
356 function symbol_indirection(c, n)
357 integer(8) :: n
358 character(n) :: c
359 character(len(c, KIND=8)) :: symbol_indirection
360 end function
361 end interface
362 integer(8) :: n
363 character(n) :: c
364 ! CHECK: BeginExternalListOutput
365 ! CHECK: %[[nload:.*]] = fir.load %[[n]] : !fir.ref<i64>
366 ! CHECK: %[[n_is_positive:.*]] = arith.cmpi sgt, %[[nload]], %c0{{.*}} : i64
367 ! CHECK: %[[len:.*]] = arith.select %[[n_is_positive]], %[[nload]], %c0{{.*}} : i64
368 ! CHECK: %[[len_cast:.*]] = fir.convert %[[len]] : (i64) -> index
369 ! CHECK: %[[cmpi:.*]] = arith.cmpi sgt, %[[len_cast]], %{{.*}} : index
370 ! CHECK: %[[select:.*]] = arith.select %[[cmpi]], %[[len_cast]], %{{.*}} : index
371 ! CHECK: fir.alloca !fir.char<1,?>(%[[select]] : index)
372 print *, symbol_indirection(c, n)
373 end subroutine
375 ! CHECK-LABEL: func @_QPtest_recursion(
376 ! CHECK-SAME: %[[res:.*]]: !fir.ref<!fir.char<1,?>>{{.*}}, %[[resLen:.*]]: index{{.*}}, %[[n:.*]]: !fir.ref<i64>{{.*}}) -> !fir.boxchar<1> {
377 function test_recursion(n) result(res)
378 integer(8) :: n
379 character(n) :: res
380 ! some_local is here to verify that local symbols that are visible in the
381 ! function interface are not instantiated by accident (that only the
382 ! symbols needed for the result are instantiated before the call).
383 ! CHECK: fir.alloca !fir.array<?xi32>, {{.*}}some_local
384 ! CHECK-NOT: fir.alloca !fir.array<?xi32>
385 integer :: some_local(n)
386 some_local(1) = n + 64
387 if (n.eq.1) then
388 res = char(some_local(1))
389 ! CHECK: else
390 else
391 ! CHECK-NOT: fir.alloca !fir.array<?xi32>
393 ! verify that the actual argument for symbol n ("n-1") is used to allocate
394 ! the result, and not the local value of symbol n.
396 ! CHECK: %[[nLoad:.*]] = fir.load %[[n]] : !fir.ref<i64>
397 ! CHECK: %[[sub:.*]] = arith.subi %[[nLoad]], %c1{{.*}} : i64
398 ! CHECK: fir.store %[[sub]] to %[[nInCall:.*]] : !fir.ref<i64>
400 ! CHECK-NOT: fir.alloca !fir.array<?xi32>
402 ! CHECK: %[[nInCallLoad:.*]] = fir.load %[[nInCall]] : !fir.ref<i64>
403 ! CHECK: %[[nInCallCast:.*]] = fir.convert %[[nInCallLoad]] : (i64) -> index
404 ! CHECK: %[[cmpi:.*]] = arith.cmpi sgt, %[[nInCallCast]], %{{.*}} : index
405 ! CHECK: %[[select:.*]] = arith.select %[[cmpi]], %[[nInCallCast]], %{{.*}} : index
406 ! CHECK: %[[tmp:.*]] = fir.alloca !fir.char<1,?>(%[[select]] : index)
408 ! CHECK-NOT: fir.alloca !fir.array<?xi32>
409 ! CHECK: fir.call @_QPtest_recursion(%[[tmp]], {{.*}}
410 res = char(some_local(1)) // test_recursion(n-1)
412 ! Verify that symbol n was not remapped to the actual argument passed
413 ! to n in the call (that the temporary mapping was cleaned-up).
415 ! CHECK: %[[nLoad2:.*]] = fir.load %[[n]] : !fir.ref<i64>
416 ! CHECK: OutputInteger64(%{{.*}}, %[[nLoad2]])
417 print *, n
418 end if
419 end function
421 ! Test call to character function for which only the result type is explicit
422 ! CHECK-LABEL:func @_QPtest_not_entirely_explicit_interface(
423 ! CHECK-SAME: %[[n_arg:.*]]: !fir.ref<i64>{{.*}}) {
424 subroutine test_not_entirely_explicit_interface(n)
425 integer(8) :: n
426 character(n) :: return_dyn_char_2
427 print *, return_dyn_char_2(10)
428 ! CHECK: %[[n:.*]] = fir.load %[[n_arg]] : !fir.ref<i64>
429 ! CHECK: %[[len:.*]] = fir.convert %[[n]] : (i64) -> index
430 ! CHECK: %[[cmpi:.*]] = arith.cmpi sgt, %[[len]], %{{.*}} : index
431 ! CHECK: %[[select:.*]] = arith.select %[[cmpi]], %[[len]], %{{.*}} : index
432 ! CHECK: %[[result:.*]] = fir.alloca !fir.char<1,?>(%[[select]] : index) {bindc_name = ".result"}
433 ! CHECK: fir.call @_QPreturn_dyn_char_2(%[[result]], %[[select]], %{{.*}}) {{.*}}: (!fir.ref<!fir.char<1,?>>, index, !fir.ref<i32>) -> !fir.boxchar<1>
434 end subroutine