334 lines · plain
1! Test correct deallocation of intent(out) allocatables.2! RUN: bbc --use-desc-for-alloc=false -emit-fir -hlfir=false %s -o - | FileCheck %s --check-prefixes=CHECK,FIR3! RUN: bbc -emit-hlfir %s -o - -I nw | FileCheck %s --check-prefixes=CHECK,HLFIR4 5module mod16 type, bind(c) :: t17 integer :: i8 end type9 10 type :: t11 integer :: a12 end type13 14 type, extends(t) :: t215 integer :: b16 end type17 18 interface19 subroutine sub3(a) bind(c)20 integer, intent(out), allocatable :: a(:)21 end subroutine22 end interface23 24 interface25 subroutine sub7(t) bind(c)26 import :: t127 type(t1), allocatable, intent(out) :: t28 end subroutine29 end interface30 31contains32 subroutine sub0()33 integer, allocatable :: a(:)34 allocate(a(10))35 call sub1(a)36 end subroutine37 38 subroutine sub1(a)39 integer, intent(out), allocatable :: a(:)40 end subroutine41 42! Make sure there is no deallocation of the allocatable intent(out) on the43! caller side.44 45! CHECK-LABEL: func.func @_QMmod1Psub0()46! CHECK-NOT: fir.freemem47! CHECK: fir.call @_QMmod1Psub148 49! Check inline deallocation of allocatable intent(out) on the callee side.50 51! CHECK-LABEL: func.func @_QMmod1Psub1(52! FIR-SAME: %[[ARG0:.*]]: !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>> {fir.bindc_name = "a"})53! HLFIR: %[[ARG0:.*]]:2 = hlfir.declare {{.*}}"_QMmod1Fsub1Ea"54! CHECK: %[[BOX:.*]] = fir.load %[[ARG0]]{{[#0]*}} : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>55! CHECK: %[[BOX_ADDR:.*]] = fir.box_addr %[[BOX]] : (!fir.box<!fir.heap<!fir.array<?xi32>>>) -> !fir.heap<!fir.array<?xi32>>56! CHECK: %[[BOX_ADDR_PTR:.*]] = fir.convert %[[BOX_ADDR]] : (!fir.heap<!fir.array<?xi32>>) -> i6457! CHECK: %[[C0:.*]] = arith.constant 0 : i6458! CHECK: %[[IS_ALLOCATED:.*]] = arith.cmpi ne, %[[BOX_ADDR_PTR]], %[[C0]] : i6459! CHECK: fir.if %[[IS_ALLOCATED]] {60! CHECK: %[[BOX:.*]] = fir.load %[[ARG0]]{{[#0]*}} : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>61! CHECK: %[[BOX_ADDR:.*]] = fir.box_addr %[[BOX]] : (!fir.box<!fir.heap<!fir.array<?xi32>>>) -> !fir.heap<!fir.array<?xi32>>62! CHECK: fir.freemem %[[BOX_ADDR]] : !fir.heap<!fir.array<?xi32>>63! CHECK: %[[ZERO:.*]] = fir.zero_bits !fir.heap<!fir.array<?xi32>>64! CHECK: %[[C0:.*]] = arith.constant 0 : index65! CHECK: %[[SHAPE:.*]] = fir.shape %[[C0]] : (index) -> !fir.shape<1>66! CHECK: %[[EMBOX:.*]] = fir.embox %[[ZERO]](%[[SHAPE]]) : (!fir.heap<!fir.array<?xi32>>, !fir.shape<1>) -> !fir.box<!fir.heap<!fir.array<?xi32>>>67! CHECK: fir.store %[[EMBOX]] to %[[ARG0]]{{[#0]*}} : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>68! CHECK: }69 70 subroutine sub2()71 integer, allocatable :: a(:)72 allocate(a(10))73 call sub3(a)74 end subroutine75 76! Check inlined deallocation of allocatble intent(out) on the caller side for BIND(C).77 78! FIR-LABEL: func.func @_QMmod1Psub2()79! FIR: %[[BOX:.*]] = fir.alloca !fir.box<!fir.heap<!fir.array<?xi32>>> {bindc_name = "a", uniq_name = "_QMmod1Fsub2Ea"}80! FIR: %[[BOX_ALLOC:.*]] = fir.alloca !fir.heap<!fir.array<?xi32>> {uniq_name = "_QMmod1Fsub2Ea.addr"}81! FIR: %[[BOX_ADDR:.*]] = fir.load %[[BOX_ALLOC]] : !fir.ref<!fir.heap<!fir.array<?xi32>>>82! FIR: %[[BOX_ADDR_PTR:.*]] = fir.convert %[[BOX_ADDR]] : (!fir.heap<!fir.array<?xi32>>) -> i6483! FIR: %[[C0:.*]] = arith.constant 0 : i6484! FIR: %[[IS_ALLOCATED:.*]] = arith.cmpi ne, %[[BOX_ADDR_PTR]], %[[C0]] : i6485! FIR: fir.if %[[IS_ALLOCATED]] {86! FIR: %[[LOAD:.*]] = fir.load %[[BOX_ALLOC]] : !fir.ref<!fir.heap<!fir.array<?xi32>>>87! FIR: fir.freemem %[[LOAD]] : !fir.heap<!fir.array<?xi32>>88! FIR: %[[ZERO:.*]] = fir.zero_bits !fir.heap<!fir.array<?xi32>>89! FIR: fir.store %[[ZERO]] to %[[BOX_ALLOC]] : !fir.ref<!fir.heap<!fir.array<?xi32>>>90! FIR: }91! FIR: %[[LOAD:.*]] = fir.load %[[BOX_ALLOC]] : !fir.ref<!fir.heap<!fir.array<?xi32>>>92! FIR: %{{.*}} = fir.embox %[[LOAD]](%{{.*}}) : (!fir.heap<!fir.array<?xi32>>, !fir.shapeshift<93! FIR: fir.call @sub3(%[[BOX]]) {{.*}}: (!fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>) -> ()94 95! HLFIR-LABEL: func.func @_QMmod1Psub2(96! HLFIR: %[[ARG0:.*]]:2 = hlfir.declare {{.*}}"_QMmod1Fsub2Ea"97! HLFIR: %[[BOX:.*]] = fir.load %[[ARG0]]#0 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>98! HLFIR: %[[BOX_ADDR:.*]] = fir.box_addr %[[BOX]] : (!fir.box<!fir.heap<!fir.array<?xi32>>>) -> !fir.heap<!fir.array<?xi32>>99! HLFIR: %[[BOX_ADDR_PTR:.*]] = fir.convert %[[BOX_ADDR]] : (!fir.heap<!fir.array<?xi32>>) -> i64100! HLFIR: %[[C0:.*]] = arith.constant 0 : i64101! HLFIR: %[[IS_ALLOCATED:.*]] = arith.cmpi ne, %[[BOX_ADDR_PTR]], %[[C0]] : i64102! HLFIR: fir.if %[[IS_ALLOCATED]] {103! HLFIR: %[[BOX:.*]] = fir.load %[[ARG0]]#0 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>104! HLFIR: %[[BOX_ADDR:.*]] = fir.box_addr %[[BOX]] : (!fir.box<!fir.heap<!fir.array<?xi32>>>) -> !fir.heap<!fir.array<?xi32>>105! HLFIR: fir.freemem %[[BOX_ADDR]] : !fir.heap<!fir.array<?xi32>>106! HLFIR: %[[ZERO:.*]] = fir.zero_bits !fir.heap<!fir.array<?xi32>>107! HLFIR: %[[C0:.*]] = arith.constant 0 : index108! HLFIR: %[[SHAPE:.*]] = fir.shape %[[C0]] : (index) -> !fir.shape<1>109! HLFIR: %[[EMBOX:.*]] = fir.embox %[[ZERO]](%[[SHAPE]]) : (!fir.heap<!fir.array<?xi32>>, !fir.shape<1>) -> !fir.box<!fir.heap<!fir.array<?xi32>>>110! HLFIR: fir.store %[[EMBOX]] to %[[ARG0]]#0 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>111! HLFIR: fir.call @sub3(%[[ARG0]]#0) {{.*}}: (!fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>) -> ()112 113 subroutine sub4()114 type(t1), allocatable :: t115 call sub5(t)116 end subroutine117 118 subroutine sub5(t)119 type(t1), allocatable, intent(out) :: t120 end subroutine121 122! Make sure there is no deallocation runtime call of the allocatable intent(out)123! on the caller side.124 125! CHECK-LABEL: func.func @_QMmod1Psub4()126! FIR: %[[BOX:.*]] = fir.alloca !fir.box<!fir.heap<!fir.type<_QMmod1Tt1{{[<]?}}{i:i32}{{[>]?}}>>> {bindc_name = "t", uniq_name = "_QMmod1Fsub4Et"}127! HLFIR: %[[BOX:.*]]:2 = hlfir.declare {{.*}}"_QMmod1Fsub4Et"128! CHECK-NOT: fir.call @_FortranAAllocatableDeallocate129! CHECK: fir.call @_QMmod1Psub5(%[[BOX]]{{[#0]*}}) {{.*}}: (!fir.ref<!fir.box<!fir.heap<!fir.type<_QMmod1Tt1{{[<]?}}{i:i32}{{[>]?}}>>>>) -> ()130 131! Check deallocation of allocatble intent(out) on the callee side. Deallocation132! is done with a runtime call.133 134! CHECK-LABEL: func.func @_QMmod1Psub5(135! FIR-SAME: %[[ARG0:.*]]: !fir.ref<!fir.box<!fir.heap<!fir.type<_QMmod1Tt1{{[<]?}}{i:i32}{{[>]?}}>>>> {fir.bindc_name = "t"})136! HLFIR: %[[ARG0:.*]]:2 = hlfir.declare {{.*}}"_QMmod1Fsub5Et"137! CHECK: %[[BOX:.*]] = fir.load %[[ARG0]]{{[#0]*}} : !fir.ref<!fir.box<!fir.heap<!fir.type<_QMmod1Tt1{{[<]?}}{i:i32}{{[>]?}}>>>>138! CHECK: %[[BOX_ADDR:.*]] = fir.box_addr %[[BOX]] : (!fir.box<!fir.heap<!fir.type<_QMmod1Tt1{{[<]?}}{i:i32}{{[>]?}}>>>) -> !fir.heap<!fir.type<_QMmod1Tt1{{[<]?}}{i:i32}{{[>]?}}>>139! CHECK: %[[BOX_ADDR_PTR:.*]] = fir.convert %[[BOX_ADDR]] : (!fir.heap<!fir.type<_QMmod1Tt1{{[<]?}}{i:i32}{{[>]?}}>>) -> i64140! CHECK: %[[C0:.*]] = arith.constant 0 : i64141! CHECK: %[[IS_ALLOCATED:.*]] = arith.cmpi ne, %[[BOX_ADDR_PTR]], %[[C0]] : i64142! CHECK: fir.if %[[IS_ALLOCATED]] {143! CHECK: %[[BOX_NONE:.*]] = fir.convert %[[ARG0]]{{[#0]*}} : (!fir.ref<!fir.box<!fir.heap<!fir.type<_QMmod1Tt1{{[<]?}}{i:i32}{{[>]?}}>>>>) -> !fir.ref<!fir.box<none>>144! CHECK: %{{.*}} = fir.call @_FortranAAllocatableDeallocate(%[[BOX_NONE]], %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) {{.*}}: (!fir.ref<!fir.box<none>>, i1, !fir.box<none>, !fir.ref<i8>, i32) -> i32145 146 subroutine sub6()147 type(t1), allocatable :: t148 call sub7(t)149 end subroutine150 151! Check deallocation of allocatble intent(out) on the caller side for BIND(C).152! Deallocation is done with a runtime call.153 154! CHECK-LABEL: func.func @_QMmod1Psub6()155! FIR: %[[BOX:.*]] = fir.alloca !fir.box<!fir.heap<!fir.type<_QMmod1Tt1{{[<]?}}{i:i32}{{[>]?}}>>> {bindc_name = "t", uniq_name = "_QMmod1Fsub6Et"}156! HLFIR: %[[BOX:.*]]:2 = hlfir.declare {{.*}}"_QMmod1Fsub6Et"157! CHECK: %[[BOX_NONE:.*]] = fir.convert %[[BOX]]{{[#0]*}} : (!fir.ref<!fir.box<!fir.heap<!fir.type<_QMmod1Tt1{{[<]?}}{i:i32}{{[>]?}}>>>>) -> !fir.ref<!fir.box<none>>158! CHECK: %{{.*}} = fir.call @_FortranAAllocatableDeallocate(%[[BOX_NONE]], %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) {{.*}}: (!fir.ref<!fir.box<none>>, i1, !fir.box<none>, !fir.ref<i8>, i32) -> i32159! CHECK: fir.call @sub7(%[[BOX]]{{[#0]*}}) {{.*}}: (!fir.ref<!fir.box<!fir.heap<!fir.type<_QMmod1Tt1{{[<]?}}{i:i32}{{[>]?}}>>>>) -> ()160 161 subroutine sub8()162 integer, allocatable :: a(:)163 allocate(a(10))164 call sub9(a)165 end subroutine166 167 subroutine sub9(a)168 integer, intent(out), allocatable, optional :: a(:)169 end subroutine170 171! Make sure there is no deallocation of the allocatable intent(out) on the172! caller side.173 174! CHECK-LABEL: func.func @_QMmod1Psub8()175! CHECK-NOT: fir.freemem176! CHECK: fir.call @_QMmod1Psub9177 178! Check inline deallocation of optional allocatable intent(out) on the callee side.179 180! CHECK-LABEL: func.func @_QMmod1Psub9(181! FIR-SAME: %[[ARG0:.*]]: !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>> {fir.bindc_name = "a", fir.optional})182! HLFIR: %[[ARG0:.*]]:2 = hlfir.declare {{.*}}"_QMmod1Fsub9Ea"183! CHECK: %[[IS_PRESENT:.*]] = fir.is_present %[[ARG0]]{{[#0]*}} : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>) -> i1184! CHECK: fir.if %[[IS_PRESENT]] {185! CHECK: %[[BOX:.*]] = fir.load %[[ARG0]]{{[#0]*}} : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>186! CHECK: %[[BOX_ADDR:.*]] = fir.box_addr %[[BOX]] : (!fir.box<!fir.heap<!fir.array<?xi32>>>) -> !fir.heap<!fir.array<?xi32>>187! CHECK: %[[BOX_ADDR_PTR:.*]] = fir.convert %[[BOX_ADDR]] : (!fir.heap<!fir.array<?xi32>>) -> i64188! CHECK: %[[C0:.*]] = arith.constant 0 : i64189! CHECK: %[[IS_ALLOCATED:.*]] = arith.cmpi ne, %[[BOX_ADDR_PTR]], %[[C0]] : i64190! CHECK: fir.if %[[IS_ALLOCATED]] {191! CHECK: %[[BOX:.*]] = fir.load %[[ARG0]]{{[#0]*}} : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>192! CHECK: %[[BOX_ADDR:.*]] = fir.box_addr %[[BOX]] : (!fir.box<!fir.heap<!fir.array<?xi32>>>) -> !fir.heap<!fir.array<?xi32>>193! CHECK: fir.freemem %[[BOX_ADDR]] : !fir.heap<!fir.array<?xi32>>194! CHECK: %[[ZERO:.*]] = fir.zero_bits !fir.heap<!fir.array<?xi32>>195! CHECK: %[[C0:.*]] = arith.constant 0 : index196! CHECK: %[[SHAPE:.*]] = fir.shape %[[C0]] : (index) -> !fir.shape<1>197! CHECK: %[[EMBOX:.*]] = fir.embox %[[ZERO]](%[[SHAPE]]) : (!fir.heap<!fir.array<?xi32>>, !fir.shape<1>) -> !fir.box<!fir.heap<!fir.array<?xi32>>>198! CHECK: fir.store %[[EMBOX]] to %[[ARG0]]{{[#0]*}} : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>199! CHECK: }200! CHECK: }201 202 subroutine sub10(a)203 integer, intent(out), allocatable :: a(:)204 205 entry sub11206 end subroutine207 208! CHECK-LABEL: func.func @_QMmod1Psub10(209! FIR-SAME: %[[ARG0:.*]]: !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>> {fir.bindc_name = "a"}) {210! HLFIR: %[[ARG0:.*]]:2 = hlfir.declare {{.*}}"_QMmod1Fsub10Ea"211! CHECK: %[[LOAD:.*]] = fir.load %[[ARG0]]{{[#0]*}} : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>212! CHECK: %[[BOX_ADDR:.*]] = fir.box_addr %[[LOAD]] : (!fir.box<!fir.heap<!fir.array<?xi32>>>) -> !fir.heap<!fir.array<?xi32>>213! CHECK: %[[BOX_ADDR_PTR:.*]] = fir.convert %[[BOX_ADDR]] : (!fir.heap<!fir.array<?xi32>>) -> i64214! CHECK: %[[C0:.*]] = arith.constant 0 : i64215! CHECK: %[[IS_ALLOCATED:.*]] = arith.cmpi ne, %[[BOX_ADDR_PTR]], %[[C0]] : i64216! CHECK: fir.if %[[IS_ALLOCATED]] {217! CHECK: %[[BOX:.*]] = fir.load %[[ARG0]]{{[#0]*}} : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>218! CHECK: %[[BOX_ADDR:.*]] = fir.box_addr %[[BOX]] : (!fir.box<!fir.heap<!fir.array<?xi32>>>) -> !fir.heap<!fir.array<?xi32>>219! CHECK: fir.freemem %[[BOX_ADDR]] : !fir.heap<!fir.array<?xi32>>220! CHECK: %[[ZERO:.*]] = fir.zero_bits !fir.heap<!fir.array<?xi32>>221! CHECK: %[[C0:.*]] = arith.constant 0 : index222! CHECK: %[[SHAPE:.*]] = fir.shape %[[C0]] : (index) -> !fir.shape<1>223! CHECK: %[[EMBOX:.*]] = fir.embox %[[ZERO]](%[[SHAPE]]) : (!fir.heap<!fir.array<?xi32>>, !fir.shape<1>) -> !fir.box<!fir.heap<!fir.array<?xi32>>>224! CHECK: fir.store %[[EMBOX]] to %[[ARG0]]{{[#0]*}} : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>225! CHECK: }226 227! CHECK-LABEL: func.func @_QMmod1Psub11() {228! CHECK-NOT: fir.freemem229 230 subroutine sub12(a)231 integer, intent(out), allocatable :: a(:)232 entry sub13(a)233 end subroutine234 235! CHECK-LABEL: func.func @_QMmod1Psub12(236! FIR-SAME: %[[ARG0:.*]]: !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>> {fir.bindc_name = "a"}) {237! HLFIR: %[[ARG0:.*]]:2 = hlfir.declare {{.*}}"_QMmod1Fsub12Ea"238! CHECK: %[[LOAD:.*]] = fir.load %[[ARG0]]{{[#0]*}} : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>239! CHECK: %[[BOX_ADDR:.*]] = fir.box_addr %[[LOAD]] : (!fir.box<!fir.heap<!fir.array<?xi32>>>) -> !fir.heap<!fir.array<?xi32>>240! CHECK: %[[BOX_ADDR_PTR:.*]] = fir.convert %[[BOX_ADDR]] : (!fir.heap<!fir.array<?xi32>>) -> i64241! CHECK: %[[C0:.*]] = arith.constant 0 : i64242! CHECK: %[[IS_ALLOCATED:.*]] = arith.cmpi ne, %[[BOX_ADDR_PTR]], %[[C0]] : i64243! CHECK: fir.if %[[IS_ALLOCATED]] {244! CHECK: %[[BOX:.*]] = fir.load %[[ARG0]]{{[#0]*}} : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>245! CHECK: %[[BOX_ADDR:.*]] = fir.box_addr %[[BOX]] : (!fir.box<!fir.heap<!fir.array<?xi32>>>) -> !fir.heap<!fir.array<?xi32>>246! CHECK: fir.freemem %[[BOX_ADDR]] : !fir.heap<!fir.array<?xi32>>247! CHECK: %[[ZERO:.*]] = fir.zero_bits !fir.heap<!fir.array<?xi32>>248! CHECK: %[[C0:.*]] = arith.constant 0 : index249! CHECK: %[[SHAPE:.*]] = fir.shape %[[C0]] : (index) -> !fir.shape<1>250! CHECK: %[[EMBOX:.*]] = fir.embox %[[ZERO]](%[[SHAPE]]) : (!fir.heap<!fir.array<?xi32>>, !fir.shape<1>) -> !fir.box<!fir.heap<!fir.array<?xi32>>>251! CHECK: fir.store %[[EMBOX]] to %[[ARG0]]{{[#0]*}} : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>252! CHECK: }253 254! CHECK-LABEL: func.func @_QMmod1Psub13(255! FIR-SAME: %[[ARG0:.*]]: !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>> {fir.bindc_name = "a"}) {256! HLFIR: %[[ARG0:.*]]:2 = hlfir.declare {{.*}}"_QMmod1Fsub12Ea"257! CHECK: %[[LOAD:.*]] = fir.load %[[ARG0]]{{[#0]*}} : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>258! CHECK: %[[BOX_ADDR:.*]] = fir.box_addr %[[LOAD]] : (!fir.box<!fir.heap<!fir.array<?xi32>>>) -> !fir.heap<!fir.array<?xi32>>259! CHECK: %[[BOX_ADDR_PTR:.*]] = fir.convert %[[BOX_ADDR]] : (!fir.heap<!fir.array<?xi32>>) -> i64260! CHECK: %[[C0:.*]] = arith.constant 0 : i64261! CHECK: %[[IS_ALLOCATED:.*]] = arith.cmpi ne, %[[BOX_ADDR_PTR]], %[[C0]] : i64262! CHECK: fir.if %[[IS_ALLOCATED]] {263! CHECK: %[[BOX:.*]] = fir.load %[[ARG0]]{{[#0]*}} : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>264! CHECK: %[[BOX_ADDR:.*]] = fir.box_addr %[[BOX]] : (!fir.box<!fir.heap<!fir.array<?xi32>>>) -> !fir.heap<!fir.array<?xi32>>265! CHECK: fir.freemem %[[BOX_ADDR]] : !fir.heap<!fir.array<?xi32>>266! CHECK: %[[ZERO:.*]] = fir.zero_bits !fir.heap<!fir.array<?xi32>>267! CHECK: %[[C0:.*]] = arith.constant 0 : index268! CHECK: %[[SHAPE:.*]] = fir.shape %[[C0]] : (index) -> !fir.shape<1>269! CHECK: %[[EMBOX:.*]] = fir.embox %[[ZERO]](%[[SHAPE]]) : (!fir.heap<!fir.array<?xi32>>, !fir.shape<1>) -> !fir.box<!fir.heap<!fir.array<?xi32>>>270! CHECK: fir.store %[[EMBOX]] to %[[ARG0]]{{[#0]*}} : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>271! CHECK: }272 273 274 subroutine sub14(p)275 class(t), intent(out), allocatable :: p276 end subroutine277 278! CHECK-LABEL: func.func @_QMmod1Psub14(279! FIR-SAME: %[[ARG0:.*]]: !fir.ref<!fir.class<!fir.heap<!fir.type<_QMmod1Tt{a:i32}>>>> {fir.bindc_name = "p"}) {280! HLFIR: %[[ARG0:.*]]:2 = hlfir.declare {{.*}}"_QMmod1Fsub14Ep"281! CHECK: %[[BOX:.*]] = fir.load %[[ARG0]]{{[#0]*}} : !fir.ref<!fir.class<!fir.heap<!fir.type<_QMmod1Tt{a:i32}>>>>282! CHECK: %[[BOX_ADDR:.*]] = fir.box_addr %[[BOX]] : (!fir.class<!fir.heap<!fir.type<_QMmod1Tt{a:i32}>>>) -> !fir.heap<!fir.type<_QMmod1Tt{a:i32}>>283! CHECK: %[[BOX_ADDR_PTR:.*]] = fir.convert %[[BOX_ADDR]] : (!fir.heap<!fir.type<_QMmod1Tt{a:i32}>>) -> i64284! CHECK: %[[C0:.*]] = arith.constant 0 : i64285! CHECK: %[[IS_ALLOCATED:.*]] = arith.cmpi ne, %[[BOX_ADDR_PTR]], %[[C0]] : i64286! CHECK: fir.if %[[IS_ALLOCATED]] {287! CHECK: %[[TYPE_DESC:.*]] = fir.type_desc !fir.type<_QMmod1Tt{a:i32}>288! CHECK: %[[BOX_NONE:.*]] = fir.convert %[[ARG0]]{{[#0]*}} : (!fir.ref<!fir.class<!fir.heap<!fir.type<_QMmod1Tt{a:i32}>>>>) -> !fir.ref<!fir.box<none>>289! CHECK: %[[TYPE_NONE:.*]] = fir.convert %[[TYPE_DESC]] : (!fir.tdesc<!fir.type<_QMmod1Tt{a:i32}>>) -> !fir.ref<none>290! CHECK: %{{.*}} = fir.call @_FortranAAllocatableDeallocatePolymorphic(%[[BOX_NONE]], %[[TYPE_NONE]], %{{.*}}, %{{.*}}, %{{.*}}) {{.*}} : (!fir.ref<!fir.box<none>>, !fir.ref<none>, i1, !fir.box<none>, !fir.ref<i8>, i32) -> i32291! CHECK: }292 293 subroutine sub15(p)294 class(*), intent(out), allocatable :: p295 end subroutine296 297! CHECK-LABEL: func.func @_QMmod1Psub15(298! FIR-SAME: %[[ARG0:.*]]: !fir.ref<!fir.class<!fir.heap<none>>> {fir.bindc_name = "p"}) {299! HLFIR: %[[ARG0:.*]]:2 = hlfir.declare {{.*}}"_QMmod1Fsub15Ep"300! CHECK: %[[BOX:.*]] = fir.load %[[ARG0]]{{[#0]*}} : !fir.ref<!fir.class<!fir.heap<none>>>301! CHECK: %[[BOX_ADDR:.*]] = fir.box_addr %[[BOX]] : (!fir.class<!fir.heap<none>>) -> !fir.heap<none>302! CHECK: %[[BOX_ADDR_PTR:.*]] = fir.convert %[[BOX_ADDR]] : (!fir.heap<none>) -> i64303! CHECK: %[[C0:.*]] = arith.constant 0 : i64304! CHECK: %[[IS_ALLOCATED:.*]] = arith.cmpi ne, %[[BOX_ADDR_PTR]], %[[C0]] : i64305! CHECK: fir.if %[[IS_ALLOCATED]] {306! CHECK: %[[NULL_TYPE_DESC:.*]] = fir.zero_bits !fir.ref<none>307! CHECK: %[[BOX_NONE:.*]] = fir.convert %[[ARG0]]{{[#0]*}} : (!fir.ref<!fir.class<!fir.heap<none>>>) -> !fir.ref<!fir.box<none>>308! CHECK: %{{.*}} = fir.call @_FortranAAllocatableDeallocatePolymorphic(%[[BOX_NONE]], %[[NULL_TYPE_DESC]], %{{.*}}, %{{.*}}, %{{.*}}) {{.*}} : (!fir.ref<!fir.box<none>>, !fir.ref<none>, i1, !fir.box<none>, !fir.ref<i8>, i32) -> i32309! CHECK: }310 311 subroutine sub16(p)312 class(t), optional, intent(out), allocatable :: p313 end subroutine314 315! CHECK-LABEL: func.func @_QMmod1Psub16(316! FIR-SAME: %[[ARG0:.*]]: !fir.ref<!fir.class<!fir.heap<!fir.type<_QMmod1Tt{a:i32}>>>> {fir.bindc_name = "p", fir.optional}) {317! HLFIR: %[[ARG0:.*]]:2 = hlfir.declare {{.*}}"_QMmod1Fsub16Ep"318! CHECK: %[[IS_PRESENT:.*]] = fir.is_present %[[ARG0]]{{[#0]*}} : (!fir.ref<!fir.class<!fir.heap<!fir.type<_QMmod1Tt{a:i32}>>>>) -> i1319! CHECK: fir.if %[[IS_PRESENT]] {320! CHECK: %[[BOX:.*]] = fir.load %[[ARG0]]{{[#0]*}} : !fir.ref<!fir.class<!fir.heap<!fir.type<_QMmod1Tt{a:i32}>>>>321! CHECK: %[[BOX_ADDR:.*]] = fir.box_addr %[[BOX]] : (!fir.class<!fir.heap<!fir.type<_QMmod1Tt{a:i32}>>>) -> !fir.heap<!fir.type<_QMmod1Tt{a:i32}>>322! CHECK: %[[BOX_ADDR_PTR:.*]] = fir.convert %[[BOX_ADDR]] : (!fir.heap<!fir.type<_QMmod1Tt{a:i32}>>) -> i64323! CHECK: %[[C0:.*]] = arith.constant 0 : i64324! CHECK: %[[IS_ALLOCATED:.*]] = arith.cmpi ne, %[[BOX_ADDR_PTR]], %[[C0]] : i64325! CHECK: fir.if %[[IS_ALLOCATED]] {326! CHECK: %[[TYPE_DESC:.*]] = fir.type_desc !fir.type<_QMmod1Tt{a:i32}>327! CHECK: %[[BOX_NONE:.*]] = fir.convert %[[ARG0]]{{[#0]*}} : (!fir.ref<!fir.class<!fir.heap<!fir.type<_QMmod1Tt{a:i32}>>>>) -> !fir.ref<!fir.box<none>>328! CHECK: %[[TYPE_NONE:.*]] = fir.convert %[[TYPE_DESC]] : (!fir.tdesc<!fir.type<_QMmod1Tt{a:i32}>>) -> !fir.ref<none>329! CHECK: %{{.*}} = fir.call @_FortranAAllocatableDeallocatePolymorphic(%[[BOX_NONE]], %[[TYPE_NONE]], %{{.*}}, %{{.*}}, %{{.*}}) {{.*}} : (!fir.ref<!fir.box<none>>, !fir.ref<none>, i1, !fir.box<none>, !fir.ref<i8>, i32) -> i32330! CHECK: }331! CHECK: }332 333end module334