xref: /llvm-project/flang/test/Lower/implicit-call-mismatch.f90 (revision c4204c0b29a6721267b1bcbaeedd7b1118e42396)
1! Test questionable but existing abuses of implicit interfaces.
2! Lowering must close the eyes and do as if it did not know
3! about the function definition since semantic lets these
4! programs through with a warning.
5! RUN: bbc -emit-fir -hlfir=false %s -o - | FileCheck %s
6
7! Test reference to non-char procedure conversion.
8
9subroutine takes_proc(proc)
10  real(8), external :: proc
11end subroutine
12
13subroutine pass_int_to_proc(a)
14  integer(4) :: a
15  call takes_proc(a)
16end subroutine
17! CHECK-LABEL: func.func @_QPpass_int_to_proc(
18! CHECK-SAME: %[[arg0:.*]]: !fir.ref<i32>
19! CHECK: %[[procAddr:.*]] = fir.convert %[[arg0]] : (!fir.ref<i32>) -> (() -> ())
20! CHECK: %[[boxProc:.*]] = fir.emboxproc %[[procAddr]] : (() -> ()) -> !fir.boxproc<() -> ()>
21! CHECK: fir.call @_QPtakes_proc(%[[boxProc]]) {{.*}}: (!fir.boxproc<() -> ()>) -> ()
22
23subroutine pass_logical_to_proc(a)
24  logical(4) :: a
25  call takes_proc(a)
26end subroutine
27! CHECK-LABEL: func.func @_QPpass_logical_to_proc(
28! CHECK-SAME: %[[arg0:.*]]: !fir.ref<!fir.logical<4>>
29! CHECK: %[[procAddr:.*]] = fir.convert %[[arg0]] : (!fir.ref<!fir.logical<4>>) -> (() -> ())
30! CHECK: %[[boxProc:.*]] = fir.emboxproc %[[procAddr]] : (() -> ()) -> !fir.boxproc<() -> ()>
31! CHECK: fir.call @_QPtakes_proc(%[[boxProc]]) {{.*}}: (!fir.boxproc<() -> ()>) -> ()
32
33subroutine pass_real_to_proc(a)
34  real(8) :: a
35  call takes_proc(a)
36end subroutine
37! CHECK-LABEL: func.func @_QPpass_real_to_proc(
38! CHECK-SAME: %[[arg0:.*]]: !fir.ref<f64>
39! CHECK: %[[procAddr:.*]] = fir.convert %[[arg0]] : (!fir.ref<f64>) -> (() -> ())
40! CHECK: %[[boxProc:.*]] = fir.emboxproc %[[procAddr]] : (() -> ()) -> !fir.boxproc<() -> ()>
41! CHECK: fir.call @_QPtakes_proc(%[[boxProc]]) {{.*}}: (!fir.boxproc<() -> ()>) -> ()
42
43subroutine pass_complex_to_proc(a)
44  complex(4) :: a
45  call takes_proc(a)
46end subroutine
47! CHECK-LABEL: func.func @_QPpass_complex_to_proc(
48! CHECK-SAME: %[[arg0:.*]]: !fir.ref<complex<f32>>
49! CHECK: %[[procAddr:.*]] = fir.convert %[[arg0]] : (!fir.ref<complex<f32>>) -> (() -> ())
50! CHECK: %[[boxProc:.*]] = fir.emboxproc %[[procAddr]] : (() -> ()) -> !fir.boxproc<() -> ()>
51! CHECK: fir.call @_QPtakes_proc(%[[boxProc]]) {{.*}}: (!fir.boxproc<() -> ()>) -> ()
52
53subroutine pass_char_to_proc(a)
54  character(8) :: a
55  call takes_proc(a)
56end subroutine
57! CHECK-LABEL: func.func @_QPpass_char_to_proc(
58! CHECK-SAME: %[[arg0:.*]]: !fir.boxchar<1>
59! CHECK: %[[charAndLen:.*]]:2 = fir.unboxchar %[[arg0]] : (!fir.boxchar<1>) -> (!fir.ref<!fir.char<1,?>>, index)
60! CHECK: %[[charRef:.*]] = fir.convert %[[charAndLen]]#0 : (!fir.ref<!fir.char<1,?>>) -> !fir.ref<!fir.char<1,8>>
61! CHECK: %[[procAddr:.*]] = fir.convert %[[charRef]] : (!fir.ref<!fir.char<1,8>>) -> (() -> ())
62! CHECK: %[[boxProc:.*]] = fir.emboxproc %[[procAddr]] : (() -> ()) -> !fir.boxproc<() -> ()>
63! CHECK: fir.call @_QPtakes_proc(%[[boxProc]]) {{.*}}: (!fir.boxproc<() -> ()>) -> ()
64
65subroutine pass_dt_to_proc(a)
66  type :: dt
67    integer(4) :: i, j
68  end type
69  type(dt) :: a
70
71  call takes_proc(a)
72end subroutine
73! CHECK-LABEL: func.func @_QPpass_dt_to_proc(
74! CHECK-SAME: %[[arg0:.*]]: !fir.ref<!fir.type<_QFpass_dt_to_procTdt{i:i32,j:i32}>>
75! CHECK: %[[procAddr:.*]] = fir.convert %[[arg0]] : (!fir.ref<!fir.type<_QFpass_dt_to_procTdt{i:i32,j:i32}>>) -> (() -> ())
76! CHECK: %[[boxProc:.*]] = fir.emboxproc %[[procAddr]] : (() -> ()) -> !fir.boxproc<() -> ()>
77! CHECK: fir.call @_QPtakes_proc(%[[boxProc]]) {{.*}}: (!fir.boxproc<() -> ()>) -> ()
78
79subroutine pass_array_to_proc(a)
80  integer(4) :: a(10,10)
81  call takes_proc(a)
82end subroutine
83! CHECK-LABEL: func.func @_QPpass_array_to_proc(
84! CHECK-SAME: %[[arg0:.*]]: !fir.ref<!fir.array<10x10xi32>>
85! CHECK: %[[procAddr:.*]] = fir.convert %[[arg0]] : (!fir.ref<!fir.array<10x10xi32>>) -> (() -> ())
86! CHECK: %[[boxProc:.*]] = fir.emboxproc %[[procAddr]] : (() -> ()) -> !fir.boxproc<() -> ()>
87! CHECK: fir.call @_QPtakes_proc(%[[boxProc]]) {{.*}}: (!fir.boxproc<() -> ()>) -> ()
88
89! Test procedure conversion.
90
91subroutine pass_char_proc_to_proc(a)
92  character(8), external :: a
93  call takes_proc(a)
94end subroutine
95! CHECK-LABEL: func.func @_QPpass_char_proc_to_proc(
96! CHECK-SAME: %[[arg0:.*]]: tuple<!fir.boxproc<() -> ()>, i64>
97! CHECK: %[[extract:.*]] = fir.extract_value %[[arg0]], [0 : index] : (tuple<!fir.boxproc<() -> ()>, i64>) -> !fir.boxproc<() -> ()>
98! CHECK: %[[procAddr:.*]] = fir.box_addr %[[extract]] : (!fir.boxproc<() -> ()>) -> (() -> ())
99! CHECK: %[[boxProc:.*]] = fir.emboxproc %[[procAddr]] : (() -> ()) -> !fir.boxproc<() -> ()>
100! CHECK: fir.call @_QPtakes_proc(%[[boxProc]]) {{.*}}: (!fir.boxproc<() -> ()>) -> ()
101
102subroutine pass_proc_to_proc(a)
103  external :: a
104  call takes_proc(a)
105end subroutine
106! CHECK-LABEL: func.func @_QPpass_proc_to_proc(
107! CHECK-SAME: %[[arg0:.*]]: !fir.boxproc<() -> ()>
108! CHECK: fir.call @_QPtakes_proc(%[[arg0]]) {{.*}}: (!fir.boxproc<() -> ()>) -> ()
109
110! Test conversion from procedure to other data types.
111
112! CHECK-LABEL: func.func @_QPtest_conversion_from_proc(
113subroutine test_conversion_from_proc
114  external :: proc
115
116  ! CHECK: %[[proc:.*]] = fir.address_of(@_QPproc) : () -> ()
117  ! CHECK: %[[convert:.*]] = fir.convert %[[proc]] : (() -> ()) -> !fir.ref<i32>
118  ! CHECK: fir.call @_QPpass_int_to_proc(%[[convert]])
119  call pass_int_to_proc(proc)
120
121  ! CHECK: %[[proc:.*]] = fir.address_of(@_QPproc) : () -> ()
122  ! CHECK: %[[convert:.*]] = fir.convert %[[proc]] : (() -> ()) -> !fir.ref<!fir.logical<4>>
123  ! CHECK: fir.call @_QPpass_logical_to_proc(%[[convert]])
124  call pass_logical_to_proc(proc)
125
126  ! CHECK: %[[proc:.*]] = fir.address_of(@_QPproc) : () -> ()
127  ! CHECK: %[[convert:.*]] = fir.convert %[[proc]] : (() -> ()) -> !fir.ref<f64>
128  ! CHECK: fir.call @_QPpass_real_to_proc(%[[convert]])
129  call pass_real_to_proc(proc)
130
131  ! CHECK: %[[proc:.*]] = fir.address_of(@_QPproc) : () -> ()
132  ! CHECK: %[[convert:.*]] = fir.convert %[[proc]] : (() -> ()) -> !fir.ref<complex<f32>>
133  ! CHECK: fir.call @_QPpass_complex_to_proc(%[[convert]])
134  call pass_complex_to_proc(proc)
135
136  ! CHECK: %[[proc:.*]] = fir.address_of(@_QPproc) : () -> ()
137  ! CHECK: %[[convert:.*]] = fir.convert %[[proc]] : (() -> ()) -> !fir.ref<!fir.char<1,?>>
138  ! CHECK: %[[box:.*]] = fir.emboxchar %[[convert]], %c0{{.*}} : (!fir.ref<!fir.char<1,?>>, index) -> !fir.boxchar<1>
139  ! CHECK: fir.call @_QPpass_char_to_proc(%[[box]])
140  call pass_char_to_proc(proc)
141
142  ! CHECK: %[[proc:.*]] = fir.address_of(@_QPproc) : () -> ()
143  ! CHECK: %[[convert:.*]] = fir.convert %[[proc]] : (() -> ()) -> !fir.ref<!fir.type<_QFpass_dt_to_procTdt{i:i32,j:i32}>>
144  ! CHECK: fir.call @_QPpass_dt_to_proc(%[[convert]])
145  call pass_dt_to_proc(proc)
146
147  ! CHECK: %[[proc:.*]] = fir.address_of(@_QPproc) : () -> ()
148  ! CHECK: %[[convert:.*]] = fir.convert %[[proc]] : (() -> ()) -> !fir.ref<!fir.array<10x10xi32>>
149  ! CHECK: fir.call @_QPpass_array_to_proc(%[[convert]])
150  call pass_array_to_proc(proc)
151
152  ! CHECK: %[[proc:.*]] = fir.address_of(@_QPproc) : () -> ()
153  ! CHECK: %[[boxProc:.*]] = fir.emboxproc %[[proc]] : (() -> ()) -> !fir.boxproc<() -> ()>
154  ! CHECK: %[[len:.*]] = fir.undefined i64
155  ! CHECK: %[[tuple:.*]] = fir.undefined tuple<!fir.boxproc<() -> ()>, i64>
156  ! CHECK: %[[tuple2:.*]] = fir.insert_value %[[tuple]], %[[boxProc]], [0 : index] : (tuple<!fir.boxproc<() -> ()>, i64>, !fir.boxproc<() -> ()>) -> tuple<!fir.boxproc<() -> ()>, i64>
157  ! CHECK: %[[tuple3:.*]] = fir.insert_value %[[tuple2]], %[[len]], [1 : index] : (tuple<!fir.boxproc<() -> ()>, i64>, i64) -> tuple<!fir.boxproc<() -> ()>, i64>
158  ! CHECK: fir.call @_QPpass_char_proc_to_proc(%[[tuple3]]) {{.*}}: (tuple<!fir.boxproc<() -> ()>, i64>) -> ()
159  call pass_char_proc_to_proc(proc)
160
161  ! CHECK: %[[proc:.*]] = fir.address_of(@_QPproc) : () -> ()
162  ! CHECK: %[[box:.*]] = fir.emboxproc %[[proc]] : (() -> ()) -> !fir.boxproc<() -> ()>
163  ! CHECK: fir.call @_QPpass_proc_to_proc(%[[box]])
164  call pass_proc_to_proc(proc)
165end subroutine
166
167! Test reference to char procedure conversion.
168
169subroutine takes_char_proc(cp)
170  character(8), external :: cp
171end subroutine
172
173subroutine pass_int_to_char_proc(a)
174  integer(4) :: a
175  call takes_char_proc(a)
176end subroutine
177! CHECK-LABEL: func.func @_QPpass_int_to_char_proc(
178! CHECK-SAME: %[[arg0:.*]]: !fir.ref<i32>
179! CHECK: %[[procAddr:.*]] = fir.convert %[[arg0]] : (!fir.ref<i32>) -> (() -> ())
180! CHECK: %[[boxProc:.*]] = fir.emboxproc %[[procAddr]] : (() -> ()) -> !fir.boxproc<() -> ()>
181! CHECK: %[[charLen:.*]] = fir.undefined i64
182! CHECK: %[[tuple:.*]] = fir.undefined tuple<!fir.boxproc<() -> ()>, i64>
183! CHECK: %[[tuple2:.*]] = fir.insert_value %[[tuple]], %[[boxProc]], [0 : index] : (tuple<!fir.boxproc<() -> ()>, i64>, !fir.boxproc<() -> ()>) -> tuple<!fir.boxproc<() -> ()>, i64>
184! CHECK: %[[tuple3:.*]] = fir.insert_value %[[tuple2]], %[[charLen]], [1 : index] : (tuple<!fir.boxproc<() -> ()>, i64>, i64) -> tuple<!fir.boxproc<() -> ()>, i64>
185! CHECK: fir.call @_QPtakes_char_proc(%[[tuple3]]) {{.*}}: (tuple<!fir.boxproc<() -> ()>, i64>) -> ()
186
187subroutine pass_logical_to_char_proc(a)
188  logical(4) :: a
189  call takes_char_proc(a)
190end subroutine
191! CHECK-LABEL: func.func @_QPpass_logical_to_char_proc(
192! CHECK-SAME: %[[arg0:.*]]: !fir.ref<!fir.logical<4>>
193! CHECK: %[[procAddr:.*]] = fir.convert %[[arg0]] : (!fir.ref<!fir.logical<4>>) -> (() -> ())
194! CHECK: %[[boxProc:.*]] = fir.emboxproc %[[procAddr]] : (() -> ()) -> !fir.boxproc<() -> ()>
195! CHECK: %[[charLen:.*]] = fir.undefined i64
196! CHECK: %[[tuple:.*]] = fir.undefined tuple<!fir.boxproc<() -> ()>, i64>
197! CHECK: %[[tuple2:.*]] = fir.insert_value %[[tuple]], %[[boxProc]], [0 : index] : (tuple<!fir.boxproc<() -> ()>, i64>, !fir.boxproc<() -> ()>) -> tuple<!fir.boxproc<() -> ()>, i64>
198! CHECK: %[[tuple3:.*]] = fir.insert_value %[[tuple2]], %[[charLen]], [1 : index] : (tuple<!fir.boxproc<() -> ()>, i64>, i64) -> tuple<!fir.boxproc<() -> ()>, i64>
199! CHECK: fir.call @_QPtakes_char_proc(%[[tuple3]]) {{.*}}: (tuple<!fir.boxproc<() -> ()>, i64>) -> ()
200
201subroutine pass_real_to_char_proc(a)
202  real(8) :: a
203  call takes_char_proc(a)
204end subroutine
205! CHECK-LABEL: func.func @_QPpass_real_to_char_proc(
206! CHECK-SAME: %[[arg0:.*]]: !fir.ref<f64>
207! CHECK: %[[procAddr:.*]] = fir.convert %[[arg0]] : (!fir.ref<f64>) -> (() -> ())
208! CHECK: %[[boxProc:.*]] = fir.emboxproc %[[procAddr]] : (() -> ()) -> !fir.boxproc<() -> ()>
209! CHECK: %[[charLen:.*]] = fir.undefined i64
210! CHECK: %[[tuple:.*]] = fir.undefined tuple<!fir.boxproc<() -> ()>, i64>
211! CHECK: %[[tuple2:.*]] = fir.insert_value %[[tuple]], %[[boxProc]], [0 : index] : (tuple<!fir.boxproc<() -> ()>, i64>, !fir.boxproc<() -> ()>) -> tuple<!fir.boxproc<() -> ()>, i64>
212! CHECK: %[[tuple3:.*]] = fir.insert_value %[[tuple2]], %[[charLen]], [1 : index] : (tuple<!fir.boxproc<() -> ()>, i64>, i64) -> tuple<!fir.boxproc<() -> ()>, i64>
213! CHECK: fir.call @_QPtakes_char_proc(%[[tuple3]]) {{.*}}: (tuple<!fir.boxproc<() -> ()>, i64>) -> ()
214
215subroutine pass_complex_to_char_proc(a)
216  complex(4) :: a
217  call takes_char_proc(a)
218end subroutine
219! CHECK-LABEL: func.func @_QPpass_complex_to_char_proc(
220! CHECK-SAME: %[[arg0:.*]]: !fir.ref<complex<f32>>
221! CHECK: %[[procAddr:.*]] = fir.convert %[[arg0]] : (!fir.ref<complex<f32>>) -> (() -> ())
222! CHECK: %[[boxProc:.*]] = fir.emboxproc %[[procAddr]] : (() -> ()) -> !fir.boxproc<() -> ()>
223! CHECK: %[[charLen:.*]] = fir.undefined i64
224! CHECK: %[[tuple:.*]] = fir.undefined tuple<!fir.boxproc<() -> ()>, i64>
225! CHECK: %[[tuple2:.*]] = fir.insert_value %[[tuple]], %[[boxProc]], [0 : index] : (tuple<!fir.boxproc<() -> ()>, i64>, !fir.boxproc<() -> ()>) -> tuple<!fir.boxproc<() -> ()>, i64>
226! CHECK: %[[tuple3:.*]] = fir.insert_value %[[tuple2]], %[[charLen]], [1 : index] : (tuple<!fir.boxproc<() -> ()>, i64>, i64) -> tuple<!fir.boxproc<() -> ()>, i64>
227! CHECK: fir.call @_QPtakes_char_proc(%[[tuple3]]) {{.*}}: (tuple<!fir.boxproc<() -> ()>, i64>) -> ()
228
229subroutine pass_char_to_char_proc(a)
230  character(8) :: a
231  call takes_char_proc(a)
232end subroutine
233! CHECK-LABEL: func.func @_QPpass_char_to_char_proc(
234! CHECK-SAME: %[[arg0:.*]]: !fir.boxchar<1>
235! CHECK: %[[charRefAndLen:.*]]:2 = fir.unboxchar %[[arg0]] : (!fir.boxchar<1>) -> (!fir.ref<!fir.char<1,?>>, index)
236! CHECK: %[[charRef:.*]] = fir.convert %[[charRefAndLen]]#0 : (!fir.ref<!fir.char<1,?>>) -> !fir.ref<!fir.char<1,8>>
237! CHECK: %[[charLen:.*]] = arith.constant 8 : index
238! CHECK: %[[procAddr:.*]] = fir.convert %[[charRef]] : (!fir.ref<!fir.char<1,8>>) -> (() -> ())
239! CHECK: %[[boxProc:.*]] = fir.emboxproc %[[procAddr]] : (() -> ()) -> !fir.boxproc<() -> ()>
240! CHECK: %[[charLen2:.*]] = fir.convert %[[charLen]] : (index) -> i64
241! CHECK: %[[tuple:.*]] = fir.undefined tuple<!fir.boxproc<() -> ()>, i64>
242! CHECK: %[[tuple2:.*]] = fir.insert_value %[[tuple]], %[[boxProc]], [0 : index] : (tuple<!fir.boxproc<() -> ()>, i64>, !fir.boxproc<() -> ()>) -> tuple<!fir.boxproc<() -> ()>, i64>
243! CHECK: %[[tuple3:.*]] = fir.insert_value %[[tuple2]], %[[charLen2]], [1 : index] : (tuple<!fir.boxproc<() -> ()>, i64>, i64) -> tuple<!fir.boxproc<() -> ()>, i64>
244! CHECK: fir.call @_QPtakes_char_proc(%[[tuple3]]) {{.*}}: (tuple<!fir.boxproc<() -> ()>, i64>) -> ()
245
246subroutine pass_dt_to_char_proc(a)
247  type :: dt
248    integer(4) :: i, j
249  end type
250  type(dt) :: a
251
252  call takes_char_proc(a)
253end subroutine
254! CHECK-LABEL: func.func @_QPpass_dt_to_char_proc(
255! CHECK-SAME: %[[arg0:.*]]: !fir.ref<!fir.type<_QFpass_dt_to_char_procTdt{i:i32,j:i32}>>
256! CHECK: %[[procAddr:.*]] = fir.convert %[[arg0]] : (!fir.ref<!fir.type<_QFpass_dt_to_char_procTdt{i:i32,j:i32}>>) -> (() -> ())
257! CHECK: %[[boxProc:.*]] = fir.emboxproc %[[procAddr]] : (() -> ()) -> !fir.boxproc<() -> ()>
258! CHECK: %[[charLen:.*]] = fir.undefined i64
259! CHECK: %[[tuple:.*]] = fir.undefined tuple<!fir.boxproc<() -> ()>, i64>
260! CHECK: %[[tuple2:.*]] = fir.insert_value %[[tuple]], %[[boxProc]], [0 : index] : (tuple<!fir.boxproc<() -> ()>, i64>, !fir.boxproc<() -> ()>) -> tuple<!fir.boxproc<() -> ()>, i64>
261! CHECK: %[[tuple3:.*]] = fir.insert_value %[[tuple2]], %[[charLen]], [1 : index] : (tuple<!fir.boxproc<() -> ()>, i64>, i64) -> tuple<!fir.boxproc<() -> ()>, i64>
262! CHECK: fir.call @_QPtakes_char_proc(%[[tuple3]]) {{.*}}: (tuple<!fir.boxproc<() -> ()>, i64>) -> ()
263
264subroutine pass_array_to_char_proc(a)
265  integer(4) :: a(10,10)
266  call takes_char_proc(a)
267end subroutine
268! CHECK-LABEL: func.func @_QPpass_array_to_char_proc(
269! CHECK-SAME: %[[arg0:.*]]: !fir.ref<!fir.array<10x10xi32>>
270! CHECK: %[[procAddr:.*]] = fir.convert %[[arg0]] : (!fir.ref<!fir.array<10x10xi32>>) -> (() -> ())
271! CHECK: %[[boxProc:.*]] = fir.emboxproc %[[procAddr]] : (() -> ()) -> !fir.boxproc<() -> ()>
272! CHECK: %[[charLen:.*]] = fir.undefined i64
273! CHECK: %[[tuple:.*]] = fir.undefined tuple<!fir.boxproc<() -> ()>, i64>
274! CHECK: %[[tuple2:.*]] = fir.insert_value %[[tuple]], %[[boxProc]], [0 : index] : (tuple<!fir.boxproc<() -> ()>, i64>, !fir.boxproc<() -> ()>) -> tuple<!fir.boxproc<() -> ()>, i64>
275! CHECK: %[[tuple3:.*]] = fir.insert_value %[[tuple2]], %[[charLen]], [1 : index] : (tuple<!fir.boxproc<() -> ()>, i64>, i64) -> tuple<!fir.boxproc<() -> ()>, i64>
276! CHECK: fir.call @_QPtakes_char_proc(%[[tuple3]]) {{.*}}: (tuple<!fir.boxproc<() -> ()>, i64>) -> ()
277
278! Test procedure conversion.
279
280subroutine pass_proc_to_char_proc(a)
281  external :: a
282  call takes_char_proc(a)
283end subroutine
284! CHECK-LABEL: func.func @_QPpass_proc_to_char_proc(
285! CHECK-SAME: %[[arg0:.*]]: !fir.boxproc<() -> ()>
286! CHECK: %[[procAddr:.*]] = fir.box_addr %[[arg0]] : (!fir.boxproc<() -> ()>) -> (() -> ())
287! CHECK: %[[boxProc:.*]] = fir.emboxproc %[[procAddr]] : (() -> ()) -> !fir.boxproc<() -> ()>
288! CHECK: %[[charLen:.*]] = fir.undefined i64
289! CHECK: %[[tuple:.*]] = fir.undefined tuple<!fir.boxproc<() -> ()>, i64>
290! CHECK: %[[tuple2:.*]] = fir.insert_value %[[tuple]], %[[boxProc]], [0 : index] : (tuple<!fir.boxproc<() -> ()>, i64>, !fir.boxproc<() -> ()>) -> tuple<!fir.boxproc<() -> ()>, i64>
291! CHECK: %[[tuple3:.*]] = fir.insert_value %[[tuple2]], %[[charLen]], [1 : index] : (tuple<!fir.boxproc<() -> ()>, i64>, i64) -> tuple<!fir.boxproc<() -> ()>, i64>
292! CHECK: fir.call @_QPtakes_char_proc(%[[tuple3]]) {{.*}}: (tuple<!fir.boxproc<() -> ()>, i64>) -> ()
293
294subroutine pass_char_proc_to_char_proc(a)
295  character(8), external :: a
296  call takes_char_proc(a)
297end subroutine
298! CHECK-LABEL: func.func @_QPpass_char_proc_to_char_proc(
299! CHECK-SAME: %[[arg0:.*]]: tuple<!fir.boxproc<() -> ()>, i64>
300! CHECK: %[[boxProc:.*]] = fir.extract_value %arg0, [0 : index] : (tuple<!fir.boxproc<() -> ()>, i64>) -> !fir.boxproc<() -> ()>
301! CHECK: %[[procAddr:.*]] = fir.box_addr %[[boxProc]] : (!fir.boxproc<() -> ()>) -> (() -> ())
302! CHECK: %[[charLen:.*]] = arith.constant 8 : i64
303! CHECK: %[[boxProc2:.*]] = fir.emboxproc %[[procAddr]] : (() -> ()) -> !fir.boxproc<() -> ()>
304! CHECK: %[[tuple:.*]] = fir.undefined tuple<!fir.boxproc<() -> ()>, i64>
305! CHECK: %[[tuple2:.*]] = fir.insert_value %[[tuple]], %[[boxProc2]], [0 : index] : (tuple<!fir.boxproc<() -> ()>, i64>, !fir.boxproc<() -> ()>) -> tuple<!fir.boxproc<() -> ()>, i64>
306! CHECK: %[[tuple3:.*]] = fir.insert_value %[[tuple2]], %[[charLen]], [1 : index] : (tuple<!fir.boxproc<() -> ()>, i64>, i64) -> tuple<!fir.boxproc<() -> ()>, i64>
307! CHECK: fir.call @_QPtakes_char_proc(%[[tuple3]]) {{.*}}: (tuple<!fir.boxproc<() -> ()>, i64>) -> ()
308
309! Test conversion from character procedure to other data types.
310
311! CHECK-LABEL: func.func @_QPtest_conversion_from_char_proc(
312subroutine test_conversion_from_char_proc
313  character(8), external :: char_proc
314
315  ! CHECK: %[[proc:.*]] = fir.address_of(@_QPchar_proc) : (!fir.ref<!fir.char<1,8>>, index) -> !fir.boxchar<1>
316  ! CHECK: %[[convert:.*]] = fir.convert %[[proc]] : ((!fir.ref<!fir.char<1,8>>, index) -> !fir.boxchar<1>) -> !fir.ref<i32>
317  ! CHECK: fir.call @_QPpass_int_to_char_proc(%[[convert]])
318  call pass_int_to_char_proc(char_proc)
319
320  ! CHECK: %[[proc:.*]] = fir.address_of(@_QPchar_proc) : (!fir.ref<!fir.char<1,8>>, index) -> !fir.boxchar<1>
321  ! CHECK: %[[convert:.*]] = fir.convert %[[proc]] : ((!fir.ref<!fir.char<1,8>>, index) -> !fir.boxchar<1>) -> !fir.ref<!fir.logical<4>>
322  ! CHECK: fir.call @_QPpass_logical_to_char_proc(%[[convert]])
323  call pass_logical_to_char_proc(char_proc)
324
325  ! CHECK: %[[proc:.*]] = fir.address_of(@_QPchar_proc) : (!fir.ref<!fir.char<1,8>>, index) -> !fir.boxchar<1>
326  ! CHECK: %[[convert:.*]] = fir.convert %[[proc]] : ((!fir.ref<!fir.char<1,8>>, index) -> !fir.boxchar<1>) -> !fir.ref<f64>
327  ! CHECK: fir.call @_QPpass_real_to_char_proc(%[[convert]])
328  call pass_real_to_char_proc(char_proc)
329
330  ! CHECK: %[[proc:.*]] = fir.address_of(@_QPchar_proc) : (!fir.ref<!fir.char<1,8>>, index) -> !fir.boxchar<1>
331  ! CHECK: %[[convert:.*]] = fir.convert %[[proc]] : ((!fir.ref<!fir.char<1,8>>, index) -> !fir.boxchar<1>) -> !fir.ref<complex<f32>>
332  ! CHECK: fir.call @_QPpass_complex_to_char_proc(%[[convert]])
333  call pass_complex_to_char_proc(char_proc)
334
335  ! CHECK: %[[proc:.*]] = fir.address_of(@_QPchar_proc) : (!fir.ref<!fir.char<1,8>>, index) -> !fir.boxchar<1>
336  ! CHECK: %[[convert:.*]] = fir.convert %[[proc]] : ((!fir.ref<!fir.char<1,8>>, index) -> !fir.boxchar<1>) -> !fir.ref<!fir.char<1,?>>
337  ! CHECK: %[[len:.*]] = fir.undefined index
338  ! CHECK: %[[box:.*]] = fir.emboxchar %[[convert]], %[[len]] : (!fir.ref<!fir.char<1,?>>, index) -> !fir.boxchar<1>
339  ! CHECK: fir.call @_QPpass_char_to_char_proc(%[[box]])
340  call pass_char_to_char_proc(char_proc)
341
342  ! CHECK: %[[proc:.*]] = fir.address_of(@_QPchar_proc) : (!fir.ref<!fir.char<1,8>>, index) -> !fir.boxchar<1>
343  ! CHECK: %[[convert:.*]] = fir.convert %[[proc]] : ((!fir.ref<!fir.char<1,8>>, index) -> !fir.boxchar<1>) -> !fir.ref<!fir.type<_QFpass_dt_to_char_procTdt{i:i32,j:i32}>>
344  ! CHECK: fir.call @_QPpass_dt_to_char_proc(%[[convert]])
345  call pass_dt_to_char_proc(char_proc)
346
347  ! CHECK: %[[proc:.*]] = fir.address_of(@_QPchar_proc) : (!fir.ref<!fir.char<1,8>>, index) -> !fir.boxchar<1>
348  ! CHECK: %[[convert:.*]] = fir.convert %[[proc]] : ((!fir.ref<!fir.char<1,8>>, index) -> !fir.boxchar<1>) -> !fir.ref<!fir.array<10x10xi32>>
349  ! CHECK: fir.call @_QPpass_array_to_char_proc(%[[convert]])
350  call pass_array_to_char_proc(char_proc)
351
352  ! CHECK: %[[proc:.*]] = fir.address_of(@_QPchar_proc) : (!fir.ref<!fir.char<1,8>>, index) -> !fir.boxchar<1>
353  ! CHECK: %[[boxProc:.*]] = fir.emboxproc %[[proc]] : ((!fir.ref<!fir.char<1,8>>, index) -> !fir.boxchar<1>) -> !fir.boxproc<() -> ()>
354  ! CHECK: fir.call @_QPpass_proc_to_char_proc(%[[boxProc]])
355  call pass_proc_to_char_proc(char_proc)
356
357  ! CHECK: %[[proc:.*]] = fir.address_of(@_QPchar_proc) : (!fir.ref<!fir.char<1,8>>, index) -> !fir.boxchar<1>
358  ! CHECK: %[[len:.*]] = arith.constant 8 : i64
359  ! CHECK: %[[boxProc:.*]] = fir.emboxproc %[[proc]] : ((!fir.ref<!fir.char<1,8>>, index) -> !fir.boxchar<1>) -> !fir.boxproc<() -> ()>
360  ! CHECK: %[[tuple:.*]] = fir.undefined tuple<!fir.boxproc<() -> ()>, i64>
361  ! CHECK: %[[tuple2:.*]] = fir.insert_value %[[tuple]], %[[boxProc]], [0 : index] : (tuple<!fir.boxproc<() -> ()>, i64>, !fir.boxproc<() -> ()>) -> tuple<!fir.boxproc<() -> ()>, i64>
362  ! CHECK: %[[tuple3:.*]] = fir.insert_value %[[tuple2]], %[[len]], [1 : index] : (tuple<!fir.boxproc<() -> ()>, i64>, i64) -> tuple<!fir.boxproc<() -> ()>, i64>
363  ! CHECK: fir.call @_QPpass_char_proc_to_char_proc(%[[tuple3]])
364  call pass_char_proc_to_char_proc(char_proc)
365end subroutine
366