! RUN: bbc -emit-fir %s -o - | FileCheck %s ! Test allocatable dummy argument on callee side ! CHECK-LABEL: func @_QPtest_scalar( ! CHECK-SAME: %[[arg0:.*]]: !fir.ref>>{{.*}}) subroutine test_scalar(x) real, allocatable :: x print *, x ! CHECK: %[[box:.*]] = fir.load %[[arg0]] : !fir.ref>> ! CHECK: %[[addr:.*]] = fir.box_addr %[[box]] : (!fir.box>) -> !fir.heap ! CHECK: %[[val:.*]] = fir.load %[[addr]] : !fir.heap end subroutine ! CHECK-LABEL: func @_QPtest_array( ! CHECK-SAME: %[[arg0:.*]]: !fir.ref>>>{{.*}}) subroutine test_array(x) integer, allocatable :: x(:,:) print *, x(1,2) ! CHECK: %[[box:.*]] = fir.load %[[arg0]] : !fir.ref>>> ! CHECK-DAG: fir.box_addr %[[box]] : (!fir.box>>) -> !fir.heap> ! CHECK-DAG: fir.box_dims %[[box]], %c0{{.*}} : (!fir.box>>, index) -> (index, index, index) ! CHECK-DAG: fir.box_dims %[[box]], %c1{{.*}} : (!fir.box>>, index) -> (index, index, index) end subroutine ! CHECK-LABEL: func @_QPtest_char_scalar_deferred( ! CHECK-SAME: %[[arg0:.*]]: !fir.ref>>>{{.*}}) subroutine test_char_scalar_deferred(c) character(:), allocatable :: c external foo1 call foo1(c) ! CHECK: %[[box:.*]] = fir.load %[[arg0]] : !fir.ref>>> ! CHECK-DAG: %[[addr:.*]] = fir.box_addr %[[box]] : (!fir.box>>) -> !fir.heap> ! CHECK-DAG: %[[len:.*]] = fir.box_elesize %[[box]] : (!fir.box>>) -> index ! CHECK-DAG: %[[addr_cast:.*]] = fir.convert %[[addr]] : (!fir.heap>) -> !fir.ref> ! CHECK: %[[boxchar:.*]] = fir.emboxchar %[[addr_cast]], %[[len]] : (!fir.ref>, index) -> !fir.boxchar<1> ! CHECK: fir.call @_QPfoo1(%[[boxchar]]) : (!fir.boxchar<1>) -> () end subroutine ! CHECK-LABEL: func @_QPtest_char_scalar_explicit_cst( ! CHECK-SAME: %[[arg0:.*]]: !fir.ref>>>{{.*}}) subroutine test_char_scalar_explicit_cst(c) character(10), allocatable :: c external foo1 call foo1(c) ! CHECK: %[[box:.*]] = fir.load %[[arg0]] : !fir.ref>>> ! CHECK-DAG: %[[addr:.*]] = fir.box_addr %[[box]] : (!fir.box>>) -> !fir.heap> ! CHECK-DAG: %[[addr_cast:.*]] = fir.convert %[[addr]] : (!fir.heap>) -> !fir.ref> ! CHECK: %[[boxchar:.*]] = fir.emboxchar %[[addr_cast]], %c10{{.*}} : (!fir.ref>, index) -> !fir.boxchar<1> ! CHECK: fir.call @_QPfoo1(%[[boxchar]]) : (!fir.boxchar<1>) -> () end subroutine ! CHECK-LABEL: func @_QPtest_char_scalar_explicit_dynamic( ! CHECK-SAME: %[[arg0:.*]]: !fir.ref>>>{{.*}}, %[[arg1:.*]]: !fir.ref{{.*}}) subroutine test_char_scalar_explicit_dynamic(c, n) integer :: n character(n), allocatable :: c external foo1 ! Check that the length expr was evaluated before the execution parts. ! CHECK: %[[raw_len:.*]] = fir.load %arg1 : !fir.ref ! CHECK: %[[c0_i32:.*]] = arith.constant 0 : i32 ! CHECK: %[[cmp:.*]] = arith.cmpi sgt, %[[raw_len]], %[[c0_i32]] : i32 ! CHECK: %[[len:.*]] = arith.select %[[cmp]], %[[raw_len]], %[[c0_i32]] : i32 n = n + 1 ! CHECK: fir.store {{.*}} to %arg1 : !fir.ref call foo1(c) ! CHECK: %[[box:.*]] = fir.load %[[arg0]] : !fir.ref>>> ! CHECK-DAG: %[[addr:.*]] = fir.box_addr %[[box]] : (!fir.box>>) -> !fir.heap> ! CHECK-DAG: %[[addr_cast:.*]] = fir.convert %[[addr]] : (!fir.heap>) -> !fir.ref> ! CHECK-DAG: %[[len_cast:.*]] = fir.convert %[[len]] : (i32) -> index ! CHECK: %[[boxchar:.*]] = fir.emboxchar %[[addr_cast]], %[[len_cast]] : (!fir.ref>, index) -> !fir.boxchar<1> ! CHECK: fir.call @_QPfoo1(%[[boxchar]]) : (!fir.boxchar<1>) -> () end subroutine ! CHECK-LABEL: func @_QPtest_char_array_deferred( ! CHECK-SAME: %[[arg0:.*]]: !fir.ref>>>>{{.*}}) subroutine test_char_array_deferred(c) character(:), allocatable :: c(:) external foo1 call foo1(c(10)) ! CHECK: %[[box:.*]] = fir.load %[[arg0]] : !fir.ref>>>> ! CHECK-DAG: %[[addr:.*]] = fir.box_addr %[[box]] : (!fir.box>>>) -> !fir.heap>> ! CHECK-DAG: fir.box_dims %[[box]], %c0{{.*}} : (!fir.box>>>, index) -> (index, index, index) ! CHECK-DAG: %[[len:.*]] = fir.box_elesize %[[box]] : (!fir.box>>>) -> index ! [...] address computation ! CHECK: %[[boxchar:.*]] = fir.emboxchar %{{.*}}, %[[len]] : (!fir.ref>, index) -> !fir.boxchar<1> ! CHECK: fir.call @_QPfoo1(%[[boxchar]]) : (!fir.boxchar<1>) -> () end subroutine ! CHECK-LABEL: func @_QPtest_char_array_explicit_cst( ! CHECK-SAME: %[[arg0:.*]]: !fir.ref>>>>{{.*}}) subroutine test_char_array_explicit_cst(c) character(10), allocatable :: c(:) external foo1 call foo1(c(3)) ! CHECK: %[[box:.*]] = fir.load %[[arg0]] : !fir.ref>>>> ! CHECK-DAG: %[[addr:.*]] = fir.box_addr %[[box]] : (!fir.box>>>) -> !fir.heap>> ! [...] address computation ! CHECK: %[[boxchar:.*]] = fir.emboxchar %{{.*}}, %c10{{.*}} : (!fir.ref>, index) -> !fir.boxchar<1> ! CHECK: fir.call @_QPfoo1(%[[boxchar]]) : (!fir.boxchar<1>) -> () end subroutine ! CHECK-LABEL: func @_QPtest_char_array_explicit_dynamic( ! CHECK-SAME: %[[arg0:.*]]: !fir.ref>>>>{{.*}}, %[[arg1:.*]]: !fir.ref{{.*}}) subroutine test_char_array_explicit_dynamic(c, n) integer :: n character(n), allocatable :: c(:) external foo1 ! Check that the length expr was evaluated before the execution parts. ! CHECK: %[[raw_len:.*]] = fir.load %arg1 : !fir.ref ! CHECK: %[[c0_i32:.*]] = arith.constant 0 : i32 ! CHECK: %[[cmp:.*]] = arith.cmpi sgt, %[[raw_len]], %[[c0_i32]] : i32 ! CHECK: %[[len:.*]] = arith.select %[[cmp]], %[[raw_len]], %[[c0_i32]] : i32 n = n + 1 ! CHECK: fir.store {{.*}} to %arg1 : !fir.ref call foo1(c(1)) ! CHECK: %[[box:.*]] = fir.load %[[arg0]] : !fir.ref>>>> ! CHECK-DAG: %[[addr:.*]] = fir.box_addr %[[box]] : (!fir.box>>>) -> !fir.heap>> ! [...] address computation ! CHECK: fir.coordinate_of ! CHECK-DAG: %[[len_cast:.*]] = fir.convert %[[len]] : (i32) -> index ! CHECK: %[[boxchar:.*]] = fir.emboxchar %{{.*}}, %[[len_cast]] : (!fir.ref>, index) -> !fir.boxchar<1> ! CHECK: fir.call @_QPfoo1(%[[boxchar]]) : (!fir.boxchar<1>) -> () end subroutine ! Check that when reading allocatable length from descriptor, the width is taking ! into account when the kind is not 1. ! CHECK-LABEL: func @_QPtest_char_scalar_deferred_k2( ! CHECK-SAME: %[[arg0:.*]]: !fir.ref>>>{{.*}}) subroutine test_char_scalar_deferred_k2(c) character(kind=2, len=:), allocatable :: c external foo2 call foo2(c) ! CHECK: %[[box:.*]] = fir.load %[[arg0]] : !fir.ref>>> ! CHECK-DAG: %[[addr:.*]] = fir.box_addr %[[box]] : (!fir.box>>) -> !fir.heap> ! CHECK-DAG: %[[size:.*]] = fir.box_elesize %[[box]] : (!fir.box>>) -> index ! CHECK-DAG: %[[len:.*]] = arith.divsi %[[size]], %c2{{.*}} : index ! CHECK-DAG: %[[addr_cast:.*]] = fir.convert %[[addr]] : (!fir.heap>) -> !fir.ref> ! CHECK: %[[boxchar:.*]] = fir.emboxchar %[[addr_cast]], %[[len]] : (!fir.ref>, index) -> !fir.boxchar<2> ! CHECK: fir.call @_QPfoo2(%[[boxchar]]) : (!fir.boxchar<2>) -> () end subroutine