! Test lowering of allocatable components ! RUN: %flang_fc1 -emit-hlfir %s -o - | FileCheck %s module acomp implicit none type t real :: x integer :: i end type interface subroutine takes_real_scalar(x) real :: x end subroutine subroutine takes_char_scalar(x) character(*) :: x end subroutine subroutine takes_derived_scalar(x) import t type(t) :: x end subroutine subroutine takes_real_array(x) real :: x(:) end subroutine subroutine takes_char_array(x) character(*) :: x(:) end subroutine subroutine takes_derived_array(x) import t type(t) :: x(:) end subroutine subroutine takes_real_scalar_pointer(x) real, allocatable :: x end subroutine subroutine takes_real_array_pointer(x) real, allocatable :: x(:) end subroutine subroutine takes_logical(x) logical :: x end subroutine end interface type real_a0 real, allocatable :: p end type type real_a1 real, allocatable :: p(:) end type type cst_char_a0 character(10), allocatable :: p end type type cst_char_a1 character(10), allocatable :: p(:) end type type def_char_a0 character(:), allocatable :: p end type type def_char_a1 character(:), allocatable :: p(:) end type type derived_a0 type(t), allocatable :: p end type type derived_a1 type(t), allocatable :: p(:) end type real, target :: real_target, real_array_target(100) character(10), target :: char_target, char_array_target(100) contains ! ----------------------------------------------------------------------------- ! Test allocatable component references ! ----------------------------------------------------------------------------- ! CHECK-LABEL: func @_QMacompPref_scalar_real_a( ! CHECK-SAME: %[[arg0:.*]]: !fir.ref>}>>{{.*}}, %[[arg1:.*]]: !fir.ref>>}>>{{.*}}, %[[arg2:.*]]: !fir.ref>}>>>{{.*}}, %[[arg3:.*]]: !fir.ref>>}>>>{{.*}}) { subroutine ref_scalar_real_a(a0_0, a1_0, a0_1, a1_1) type(real_a0) :: a0_0, a0_1(100) type(real_a1) :: a1_0, a1_1(100) ! CHECK: %[[a0_0_decl:.*]]:2 = hlfir.declare %[[arg0]]{{.*}}{uniq_name = "_QMacompFref_scalar_real_aEa0_0"} ! CHECK: %[[a0_1_decl:.*]]:2 = hlfir.declare %[[arg2]](%{{.*}}){{.*}}{uniq_name = "_QMacompFref_scalar_real_aEa0_1"} ! CHECK: %[[a1_0_decl:.*]]:2 = hlfir.declare %[[arg1]]{{.*}}{uniq_name = "_QMacompFref_scalar_real_aEa1_0"} ! CHECK: %[[a1_1_decl:.*]]:2 = hlfir.declare %[[arg3]](%{{.*}}){{.*}}{uniq_name = "_QMacompFref_scalar_real_aEa1_1"} ! CHECK: %[[coor:.*]] = hlfir.designate %[[a0_0_decl]]#0{"p"}{{.*}}{fortran_attrs = #fir.var_attrs} : (!fir.ref>}>>) -> !fir.ref>> ! CHECK: %[[load:.*]] = fir.load %[[coor]] : !fir.ref>> ! CHECK: %[[addr:.*]] = fir.box_addr %[[load]] : (!fir.box>) -> !fir.heap ! CHECK: %[[cast:.*]] = fir.convert %[[addr]] : (!fir.heap) -> !fir.ref ! CHECK: fir.call @_QPtakes_real_scalar(%[[cast]]) {{.*}}: (!fir.ref) -> () call takes_real_scalar(a0_0%p) ! CHECK: %[[a0_1_elem:.*]] = hlfir.designate %[[a0_1_decl]]#0 (%{{.*}}) : (!fir.ref>}>>>, index) -> !fir.ref>}>> ! CHECK: %[[coor:.*]] = hlfir.designate %[[a0_1_elem]]{"p"}{{.*}}{fortran_attrs = #fir.var_attrs} : (!fir.ref>}>>) -> !fir.ref>> ! CHECK: %[[load:.*]] = fir.load %[[coor]] : !fir.ref>> ! CHECK: %[[addr:.*]] = fir.box_addr %[[load]] : (!fir.box>) -> !fir.heap ! CHECK: %[[cast:.*]] = fir.convert %[[addr]] : (!fir.heap) -> !fir.ref ! CHECK: fir.call @_QPtakes_real_scalar(%[[cast]]) {{.*}}: (!fir.ref) -> () call takes_real_scalar(a0_1(5)%p) ! CHECK: %[[coor:.*]] = hlfir.designate %[[a1_0_decl]]#0{"p"}{{.*}}{fortran_attrs = #fir.var_attrs} : (!fir.ref>>}>>) -> !fir.ref>>> ! CHECK: %[[box:.*]] = fir.load %[[coor]] : !fir.ref>>> ! CHECK: %[[elem:.*]] = hlfir.designate %[[box]] (%c7{{.*}}) : (!fir.box>>, index) -> !fir.ref ! CHECK: fir.call @_QPtakes_real_scalar(%[[elem]]) {{.*}}: (!fir.ref) -> () call takes_real_scalar(a1_0%p(7)) ! CHECK: %[[a1_1_elem:.*]] = hlfir.designate %[[a1_1_decl]]#0 (%{{.*}}) : (!fir.ref>>}>>>, index) -> !fir.ref>>}>> ! CHECK: %[[coor:.*]] = hlfir.designate %[[a1_1_elem]]{"p"}{{.*}}{fortran_attrs = #fir.var_attrs} : (!fir.ref>>}>>) -> !fir.ref>>> ! CHECK: %[[box:.*]] = fir.load %[[coor]] : !fir.ref>>> ! CHECK: %[[elem:.*]] = hlfir.designate %[[box]] (%c7{{.*}}) : (!fir.box>>, index) -> !fir.ref ! CHECK: fir.call @_QPtakes_real_scalar(%[[elem]]) {{.*}}: (!fir.ref) -> () call takes_real_scalar(a1_1(5)%p(7)) end subroutine ! CHECK-LABEL: func @_QMacompPref_array_real_a( ! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref>>}>>{{.*}}, %[[VAL_1:.*]]: !fir.ref>>}>>>{{.*}}) { ! CHECK: %[[a1_0_decl:.*]]:2 = hlfir.declare %[[VAL_0]]{{.*}}{uniq_name = "_QMacompFref_array_real_aEa1_0"} ! CHECK: %[[a1_1_decl:.*]]:2 = hlfir.declare %[[VAL_1]](%{{.*}}){{.*}}{uniq_name = "_QMacompFref_array_real_aEa1_1"} ! CHECK: %[[coor:.*]] = hlfir.designate %[[a1_0_decl]]#0{"p"}{{.*}}{fortran_attrs = #fir.var_attrs} ! CHECK: %[[box:.*]] = fir.load %[[coor]] : !fir.ref>>> ! CHECK: %[[c20:.*]] = arith.constant 20 : index ! CHECK: %[[c50:.*]] = arith.constant 50 : index ! CHECK: %[[c2:.*]] = arith.constant 2 : index ! CHECK: %[[c16:.*]] = arith.constant 16 : index ! CHECK: %[[shape:.*]] = fir.shape %[[c16]] : (index) -> !fir.shape<1> ! CHECK: %[[slice:.*]] = hlfir.designate %[[box]] (%[[c20]]:%[[c50]]:%[[c2]]) shape %[[shape]] : (!fir.box>>, index, index, index, !fir.shape<1>) -> !fir.box> ! CHECK: %[[cast:.*]] = fir.convert %[[slice]] : (!fir.box>) -> !fir.box> ! CHECK: fir.call @_QPtakes_real_array(%[[cast]]) {{.*}}: (!fir.box>) -> () ! CHECK: %[[elem:.*]] = hlfir.designate %[[a1_1_decl]]#0 (%{{.*}}) : (!fir.ref>>}>>>, index) -> !fir.ref>>}>> ! CHECK: %[[coor2:.*]] = hlfir.designate %[[elem]]{"p"}{{.*}}{fortran_attrs = #fir.var_attrs} ! CHECK: %[[box2:.*]] = fir.load %[[coor2]] ! CHECK: %[[slice2:.*]] = hlfir.designate %[[box2]] (%{{.*}}:%{{.*}}:%{{.*}}) shape %{{.*}} : (!fir.box>>, index, index, index, !fir.shape<1>) -> !fir.box> ! CHECK: %[[cast2:.*]] = fir.convert %[[slice2]] : (!fir.box>) -> !fir.box> ! CHECK: fir.call @_QPtakes_real_array(%[[cast2]]) {{.*}}: (!fir.box>) -> () ! CHECK: return ! CHECK: } subroutine ref_array_real_a(a1_0, a1_1) type(real_a1) :: a1_0, a1_1(100) call takes_real_array(a1_0%p(20:50:2)) call takes_real_array(a1_1(5)%p(20:50:2)) end subroutine ! CHECK-LABEL: func @_QMacompPref_scalar_cst_char_a ! CHECK-SAME: (%[[a0_0_arg:.*]]: {{.*}}, %[[a1_0_arg:.*]]: {{.*}}, %[[a0_1_arg:.*]]: {{.*}}, %[[a1_1_arg:.*]]: {{.*}}) subroutine ref_scalar_cst_char_a(a0_0, a1_0, a0_1, a1_1) type(cst_char_a0) :: a0_0, a0_1(100) type(cst_char_a1) :: a1_0, a1_1(100) ! CHECK: %[[a0_0:.*]]:2 = hlfir.declare %[[a0_0_arg]]{{.*}}{uniq_name = "_QMacompFref_scalar_cst_char_aEa0_0"} ! CHECK: %[[a0_1:.*]]:2 = hlfir.declare %[[a0_1_arg]](%{{.*}}){{.*}}{uniq_name = "_QMacompFref_scalar_cst_char_aEa0_1"} ! CHECK: %[[a1_0:.*]]:2 = hlfir.declare %[[a1_0_arg]]{{.*}}{uniq_name = "_QMacompFref_scalar_cst_char_aEa1_0"} ! CHECK: %[[a1_1:.*]]:2 = hlfir.declare %[[a1_1_arg]](%{{.*}}){{.*}}{uniq_name = "_QMacompFref_scalar_cst_char_aEa1_1"} ! CHECK: %[[coor:.*]] = hlfir.designate %[[a0_0]]#0{"p"}{{.*}} typeparams %{{.*}} {fortran_attrs = #fir.var_attrs} ! CHECK: %[[box:.*]] = fir.load %[[coor]] ! CHECK: %[[addr:.*]] = fir.box_addr %[[box]] ! CHECK: %[[cast:.*]] = fir.convert %[[addr]] : (!fir.heap>) -> !fir.ref> ! CHECK: %[[boxchar:.*]] = fir.emboxchar %[[cast]], %c10{{.*}} ! CHECK: fir.call @_QPtakes_char_scalar(%[[boxchar]]) call takes_char_scalar(a0_0%p) ! CHECK: %[[a0_1_elem:.*]] = hlfir.designate %[[a0_1]]#0 (%{{.*}}) ! CHECK: %[[coor:.*]] = hlfir.designate %[[a0_1_elem]]{"p"}{{.*}} typeparams %{{.*}} {fortran_attrs = #fir.var_attrs} ! CHECK: %[[box:.*]] = fir.load %[[coor]] ! CHECK: %[[addr:.*]] = fir.box_addr %[[box]] ! CHECK: %[[cast:.*]] = fir.convert %[[addr]] : (!fir.heap>) -> !fir.ref> ! CHECK: %[[boxchar:.*]] = fir.emboxchar %[[cast]], %c10{{.*}} ! CHECK: fir.call @_QPtakes_char_scalar(%[[boxchar]]) call takes_char_scalar(a0_1(5)%p) ! CHECK: %[[coor:.*]] = hlfir.designate %[[a1_0]]#0{"p"}{{.*}} typeparams %{{.*}} {fortran_attrs = #fir.var_attrs} ! CHECK: %[[box:.*]] = fir.load %[[coor]] ! CHECK: %[[elem:.*]] = hlfir.designate %[[box]] (%c7{{.*}}) typeparams %{{.*}} : (!fir.box>>>, index, index) -> !fir.ref> ! CHECK: %[[boxchar:.*]] = fir.emboxchar %[[elem]], %c10{{.*}} ! CHECK: fir.call @_QPtakes_char_scalar(%[[boxchar]]) call takes_char_scalar(a1_0%p(7)) ! CHECK: %[[a1_1_elem:.*]] = hlfir.designate %[[a1_1]]#0 (%{{.*}}) ! CHECK: %[[coor:.*]] = hlfir.designate %[[a1_1_elem]]{"p"}{{.*}} typeparams %{{.*}} {fortran_attrs = #fir.var_attrs} ! CHECK: %[[box:.*]] = fir.load %[[coor]] ! CHECK: %[[elem:.*]] = hlfir.designate %[[box]] (%c7{{.*}}) typeparams %{{.*}} : (!fir.box>>>, index, index) -> !fir.ref> ! CHECK: %[[boxchar:.*]] = fir.emboxchar %[[elem]], %c10{{.*}} ! CHECK: fir.call @_QPtakes_char_scalar(%[[boxchar]]) call takes_char_scalar(a1_1(5)%p(7)) end subroutine ! CHECK-LABEL: func @_QMacompPref_scalar_def_char_a ! CHECK-SAME: (%[[a0_0_arg:.*]]: {{.*}}, %[[a1_0_arg:.*]]: {{.*}}, %[[a0_1_arg:.*]]: {{.*}}, %[[a1_1_arg:.*]]: {{.*}}) subroutine ref_scalar_def_char_a(a0_0, a1_0, a0_1, a1_1) type(def_char_a0) :: a0_0, a0_1(100) type(def_char_a1) :: a1_0, a1_1(100) ! CHECK: %[[a0_0:.*]]:2 = hlfir.declare %[[a0_0_arg]]{{.*}}{uniq_name = "_QMacompFref_scalar_def_char_aEa0_0"} ! CHECK: %[[a0_1:.*]]:2 = hlfir.declare %[[a0_1_arg]](%{{.*}}){{.*}}{uniq_name = "_QMacompFref_scalar_def_char_aEa0_1"} ! CHECK: %[[a1_0:.*]]:2 = hlfir.declare %[[a1_0_arg]]{{.*}}{uniq_name = "_QMacompFref_scalar_def_char_aEa1_0"} ! CHECK: %[[a1_1:.*]]:2 = hlfir.declare %[[a1_1_arg]](%{{.*}}){{.*}}{uniq_name = "_QMacompFref_scalar_def_char_aEa1_1"} ! CHECK: %[[coor:.*]] = hlfir.designate %[[a0_0]]#0{"p"}{{.*}}{fortran_attrs = #fir.var_attrs} ! CHECK: %[[box:.*]] = fir.load %[[coor]] ! CHECK: %[[addr:.*]] = fir.box_addr %[[box]] ! CHECK: %[[box2:.*]] = fir.load %[[coor]] ! CHECK: %[[len:.*]] = fir.box_elesize %[[box2]] ! CHECK: %[[boxchar:.*]] = fir.emboxchar %[[addr]], %[[len]] ! CHECK: fir.call @_QPtakes_char_scalar(%[[boxchar]]) call takes_char_scalar(a0_0%p) ! CHECK: %[[a0_1_elem:.*]] = hlfir.designate %[[a0_1]]#0 (%{{.*}}) ! CHECK: %[[coor:.*]] = hlfir.designate %[[a0_1_elem]]{"p"}{{.*}}{fortran_attrs = #fir.var_attrs} ! CHECK: %[[box:.*]] = fir.load %[[coor]] ! CHECK: %[[addr:.*]] = fir.box_addr %[[box]] ! CHECK: %[[box2:.*]] = fir.load %[[coor]] ! CHECK: %[[len:.*]] = fir.box_elesize %[[box2]] ! CHECK: %[[boxchar:.*]] = fir.emboxchar %[[addr]], %[[len]] ! CHECK: fir.call @_QPtakes_char_scalar(%[[boxchar]]) call takes_char_scalar(a0_1(5)%p) ! CHECK: %[[coor:.*]] = hlfir.designate %[[a1_0]]#0{"p"}{{.*}}{fortran_attrs = #fir.var_attrs} ! CHECK: %[[box:.*]] = fir.load %[[coor]] ! CHECK: %[[len:.*]] = fir.box_elesize %[[box]] ! CHECK: %[[elem:.*]] = hlfir.designate %[[box]] (%c7{{.*}}) typeparams %[[len]] : (!fir.box>>>, index, index) -> !fir.boxchar<1> ! CHECK: fir.call @_QPtakes_char_scalar(%[[elem]]) call takes_char_scalar(a1_0%p(7)) ! CHECK: %[[a1_1_elem:.*]] = hlfir.designate %[[a1_1]]#0 (%{{.*}}) ! CHECK: %[[coor:.*]] = hlfir.designate %[[a1_1_elem]]{"p"}{{.*}}{fortran_attrs = #fir.var_attrs} ! CHECK: %[[box:.*]] = fir.load %[[coor]] ! CHECK: %[[len:.*]] = fir.box_elesize %[[box]] ! CHECK: %[[elem:.*]] = hlfir.designate %[[box]] (%c7{{.*}}) typeparams %[[len]] : (!fir.box>>>, index, index) -> !fir.boxchar<1> ! CHECK: fir.call @_QPtakes_char_scalar(%[[elem]]) call takes_char_scalar(a1_1(5)%p(7)) end subroutine ! CHECK-LABEL: func @_QMacompPref_scalar_derived ! CHECK-SAME: (%[[a0_0_arg:.*]]: {{.*}}, %[[a1_0_arg:.*]]: {{.*}}, %[[a0_1_arg:.*]]: {{.*}}, %[[a1_1_arg:.*]]: {{.*}}) subroutine ref_scalar_derived(a0_0, a1_0, a0_1, a1_1) type(derived_a0) :: a0_0, a0_1(100) type(derived_a1) :: a1_0, a1_1(100) ! CHECK: %[[a0_0:.*]]:2 = hlfir.declare %[[a0_0_arg]]{{.*}}{uniq_name = "_QMacompFref_scalar_derivedEa0_0"} ! CHECK: %[[a0_1:.*]]:2 = hlfir.declare %[[a0_1_arg]](%{{.*}}){{.*}}{uniq_name = "_QMacompFref_scalar_derivedEa0_1"} ! CHECK: %[[a1_0:.*]]:2 = hlfir.declare %[[a1_0_arg]]{{.*}}{uniq_name = "_QMacompFref_scalar_derivedEa1_0"} ! CHECK: %[[a1_1:.*]]:2 = hlfir.declare %[[a1_1_arg]](%{{.*}}){{.*}}{uniq_name = "_QMacompFref_scalar_derivedEa1_1"} ! CHECK: %[[coor:.*]] = hlfir.designate %[[a0_0]]#0{"p"}{{.*}}{fortran_attrs = #fir.var_attrs} ! CHECK: %[[box:.*]] = fir.load %[[coor]] ! CHECK: %[[base:.*]] = fir.box_addr %[[box]] ! CHECK: %[[xcoor:.*]] = hlfir.designate %[[base]]{"x"} ! CHECK: fir.call @_QPtakes_real_scalar(%[[xcoor]]) call takes_real_scalar(a0_0%p%x) ! CHECK: %[[a0_1_elem:.*]] = hlfir.designate %[[a0_1]]#0 (%{{.*}}) ! CHECK: %[[coor:.*]] = hlfir.designate %[[a0_1_elem]]{"p"}{{.*}}{fortran_attrs = #fir.var_attrs} ! CHECK: %[[box:.*]] = fir.load %[[coor]] ! CHECK: %[[base:.*]] = fir.box_addr %[[box]] ! CHECK: %[[xcoor:.*]] = hlfir.designate %[[base]]{"x"} ! CHECK: fir.call @_QPtakes_real_scalar(%[[xcoor]]) call takes_real_scalar(a0_1(5)%p%x) ! CHECK: %[[coor:.*]] = hlfir.designate %[[a1_0]]#0{"p"}{{.*}}{fortran_attrs = #fir.var_attrs} ! CHECK: %[[box:.*]] = fir.load %[[coor]] ! CHECK: %[[elem:.*]] = hlfir.designate %[[box]] (%c7{{.*}}) : (!fir.box>>>, index) -> !fir.ref> ! CHECK: %[[xcoor:.*]] = hlfir.designate %[[elem]]{"x"} ! CHECK: fir.call @_QPtakes_real_scalar(%[[xcoor]]) call takes_real_scalar(a1_0%p(7)%x) ! CHECK: %[[a1_1_elem:.*]] = hlfir.designate %[[a1_1]]#0 (%{{.*}}) ! CHECK: %[[coor:.*]] = hlfir.designate %[[a1_1_elem]]{"p"}{{.*}}{fortran_attrs = #fir.var_attrs} ! CHECK: %[[box:.*]] = fir.load %[[coor]] ! CHECK: %[[elem:.*]] = hlfir.designate %[[box]] (%c7{{.*}}) : (!fir.box>>>, index) -> !fir.ref> ! CHECK: %[[xcoor:.*]] = hlfir.designate %[[elem]]{"x"} ! CHECK: fir.call @_QPtakes_real_scalar(%[[xcoor]]) call takes_real_scalar(a1_1(5)%p(7)%x) end subroutine ! ----------------------------------------------------------------------------- ! Test passing allocatable component references as allocatables ! ----------------------------------------------------------------------------- ! CHECK-LABEL: func @_QMacompPpass_real_a ! CHECK-SAME: (%[[a0_0_arg:.*]]: {{.*}}, %[[a1_0_arg:.*]]: {{.*}}, %[[a0_1_arg:.*]]: {{.*}}, %[[a1_1_arg:.*]]: {{.*}}) subroutine pass_real_a(a0_0, a1_0, a0_1, a1_1) type(real_a0) :: a0_0, a0_1(100) type(real_a1) :: a1_0, a1_1(100) ! CHECK: %[[a0_0:.*]]:2 = hlfir.declare %[[a0_0_arg]]{{.*}}{uniq_name = "_QMacompFpass_real_aEa0_0"} ! CHECK: %[[a0_1:.*]]:2 = hlfir.declare %[[a0_1_arg]](%{{.*}}){{.*}}{uniq_name = "_QMacompFpass_real_aEa0_1"} ! CHECK: %[[a1_0:.*]]:2 = hlfir.declare %[[a1_0_arg]]{{.*}}{uniq_name = "_QMacompFpass_real_aEa1_0"} ! CHECK: %[[a1_1:.*]]:2 = hlfir.declare %[[a1_1_arg]](%{{.*}}){{.*}}{uniq_name = "_QMacompFpass_real_aEa1_1"} ! CHECK: %[[coor:.*]] = hlfir.designate %[[a0_0]]#0{"p"}{{.*}}{fortran_attrs = #fir.var_attrs} ! CHECK: fir.call @_QPtakes_real_scalar_pointer(%[[coor]]) call takes_real_scalar_pointer(a0_0%p) ! CHECK: %[[a0_1_elem:.*]] = hlfir.designate %[[a0_1]]#0 (%{{.*}}) ! CHECK: %[[coor:.*]] = hlfir.designate %[[a0_1_elem]]{"p"}{{.*}}{fortran_attrs = #fir.var_attrs} ! CHECK: fir.call @_QPtakes_real_scalar_pointer(%[[coor]]) call takes_real_scalar_pointer(a0_1(5)%p) ! CHECK: %[[coor:.*]] = hlfir.designate %[[a1_0]]#0{"p"}{{.*}}{fortran_attrs = #fir.var_attrs} ! CHECK: fir.call @_QPtakes_real_array_pointer(%[[coor]]) call takes_real_array_pointer(a1_0%p) ! CHECK: %[[a1_1_elem:.*]] = hlfir.designate %[[a1_1]]#0 (%{{.*}}) ! CHECK: %[[coor:.*]] = hlfir.designate %[[a1_1_elem]]{"p"}{{.*}}{fortran_attrs = #fir.var_attrs} ! CHECK: fir.call @_QPtakes_real_array_pointer(%[[coor]]) call takes_real_array_pointer(a1_1(5)%p) end subroutine ! ----------------------------------------------------------------------------- ! Test usage in intrinsics where pointer aspect matters ! ----------------------------------------------------------------------------- ! CHECK-LABEL: func @_QMacompPallocated_p ! CHECK-SAME: (%[[a0_0_arg:.*]]: {{.*}}, %[[a1_0_arg:.*]]: {{.*}}, %[[a0_1_arg:.*]]: {{.*}}, %[[a1_1_arg:.*]]: {{.*}}) subroutine allocated_p(a0_0, a1_0, a0_1, a1_1) type(real_a0) :: a0_0, a0_1(100) type(def_char_a1) :: a1_0, a1_1(100) ! CHECK: %[[a0_0:.*]]:2 = hlfir.declare %[[a0_0_arg]]{{.*}}{uniq_name = "_QMacompFallocated_pEa0_0"} ! CHECK: %[[a0_1:.*]]:2 = hlfir.declare %[[a0_1_arg]](%{{.*}}){{.*}}{uniq_name = "_QMacompFallocated_pEa0_1"} ! CHECK: %[[a1_0:.*]]:2 = hlfir.declare %[[a1_0_arg]]{{.*}}{uniq_name = "_QMacompFallocated_pEa1_0"} ! CHECK: %[[a1_1:.*]]:2 = hlfir.declare %[[a1_1_arg]](%{{.*}}){{.*}}{uniq_name = "_QMacompFallocated_pEa1_1"} ! CHECK: %[[coor:.*]] = hlfir.designate %[[a0_0]]#0{"p"}{{.*}}{fortran_attrs = #fir.var_attrs} ! CHECK: %[[box:.*]] = fir.load %[[coor]] ! CHECK: fir.box_addr %[[box]] call takes_logical(allocated(a0_0%p)) ! CHECK: %[[a0_1_elem:.*]] = hlfir.designate %[[a0_1]]#0 (%{{.*}}) ! CHECK: %[[coor:.*]] = hlfir.designate %[[a0_1_elem]]{"p"}{{.*}}{fortran_attrs = #fir.var_attrs} ! CHECK: %[[box:.*]] = fir.load %[[coor]] ! CHECK: fir.box_addr %[[box]] call takes_logical(allocated(a0_1(5)%p)) ! CHECK: %[[coor:.*]] = hlfir.designate %[[a1_0]]#0{"p"}{{.*}}{fortran_attrs = #fir.var_attrs} ! CHECK: %[[box:.*]] = fir.load %[[coor]] ! CHECK: fir.box_addr %[[box]] call takes_logical(allocated(a1_0%p)) ! CHECK: %[[a1_1_elem:.*]] = hlfir.designate %[[a1_1]]#0 (%{{.*}}) ! CHECK: %[[coor:.*]] = hlfir.designate %[[a1_1_elem]]{"p"}{{.*}}{fortran_attrs = #fir.var_attrs} ! CHECK: %[[box:.*]] = fir.load %[[coor]] ! CHECK: fir.box_addr %[[box]] call takes_logical(allocated(a1_1(5)%p)) end subroutine ! ----------------------------------------------------------------------------- ! Test allocation ! ----------------------------------------------------------------------------- ! CHECK-LABEL: func @_QMacompPallocate_real ! CHECK-SAME: (%[[a0_0_arg:.*]]: {{.*}}, %[[a1_0_arg:.*]]: {{.*}}, %[[a0_1_arg:.*]]: {{.*}}, %[[a1_1_arg:.*]]: {{.*}}) subroutine allocate_real(a0_0, a1_0, a0_1, a1_1) type(real_a0) :: a0_0, a0_1(100) type(real_a1) :: a1_0, a1_1(100) ! CHECK: %[[a0_0:.*]]:2 = hlfir.declare %[[a0_0_arg]]{{.*}}{uniq_name = "_QMacompFallocate_realEa0_0"} ! CHECK: %[[a0_1:.*]]:2 = hlfir.declare %[[a0_1_arg]](%{{.*}}){{.*}}{uniq_name = "_QMacompFallocate_realEa0_1"} ! CHECK: %[[a1_0:.*]]:2 = hlfir.declare %[[a1_0_arg]]{{.*}}{uniq_name = "_QMacompFallocate_realEa1_0"} ! CHECK: %[[a1_1:.*]]:2 = hlfir.declare %[[a1_1_arg]](%{{.*}}){{.*}}{uniq_name = "_QMacompFallocate_realEa1_1"} ! CHECK: %[[coor:.*]] = hlfir.designate %[[a0_0]]#0{"p"}{{.*}}{fortran_attrs = #fir.var_attrs} ! CHECK: fir.store {{.*}} to %[[coor]] allocate(a0_0%p) ! CHECK: %[[a0_1_elem:.*]] = hlfir.designate %[[a0_1]]#0 (%{{.*}}) ! CHECK: %[[coor:.*]] = hlfir.designate %[[a0_1_elem]]{"p"}{{.*}}{fortran_attrs = #fir.var_attrs} ! CHECK: fir.store {{.*}} to %[[coor]] allocate(a0_1(5)%p) ! CHECK: %[[coor:.*]] = hlfir.designate %[[a1_0]]#0{"p"}{{.*}}{fortran_attrs = #fir.var_attrs} ! CHECK: fir.store {{.*}} to %[[coor]] allocate(a1_0%p(100)) ! CHECK: %[[a1_1_elem:.*]] = hlfir.designate %[[a1_1]]#0 (%{{.*}}) ! CHECK: %[[coor:.*]] = hlfir.designate %[[a1_1_elem]]{"p"}{{.*}}{fortran_attrs = #fir.var_attrs} ! CHECK: fir.store {{.*}} to %[[coor]] allocate(a1_1(5)%p(100)) end subroutine ! CHECK-LABEL: func @_QMacompPallocate_cst_char ! CHECK-SAME: (%[[a0_0_arg:.*]]: {{.*}}, %[[a1_0_arg:.*]]: {{.*}}, %[[a0_1_arg:.*]]: {{.*}}, %[[a1_1_arg:.*]]: {{.*}}) subroutine allocate_cst_char(a0_0, a1_0, a0_1, a1_1) type(cst_char_a0) :: a0_0, a0_1(100) type(cst_char_a1) :: a1_0, a1_1(100) ! CHECK: %[[a0_0:.*]]:2 = hlfir.declare %[[a0_0_arg]]{{.*}}{uniq_name = "_QMacompFallocate_cst_charEa0_0"} ! CHECK: %[[a0_1:.*]]:2 = hlfir.declare %[[a0_1_arg]](%{{.*}}){{.*}}{uniq_name = "_QMacompFallocate_cst_charEa0_1"} ! CHECK: %[[a1_0:.*]]:2 = hlfir.declare %[[a1_0_arg]]{{.*}}{uniq_name = "_QMacompFallocate_cst_charEa1_0"} ! CHECK: %[[a1_1:.*]]:2 = hlfir.declare %[[a1_1_arg]](%{{.*}}){{.*}}{uniq_name = "_QMacompFallocate_cst_charEa1_1"} ! CHECK: %[[coor:.*]] = hlfir.designate %[[a0_0]]#0{"p"}{{.*}} typeparams %{{.*}} {fortran_attrs = #fir.var_attrs} ! CHECK: fir.store {{.*}} to %[[coor]] allocate(a0_0%p) ! CHECK: %[[a0_1_elem:.*]] = hlfir.designate %[[a0_1]]#0 (%{{.*}}) ! CHECK: %[[coor:.*]] = hlfir.designate %[[a0_1_elem]]{"p"}{{.*}} typeparams %{{.*}} {fortran_attrs = #fir.var_attrs} ! CHECK: fir.store {{.*}} to %[[coor]] allocate(a0_1(5)%p) ! CHECK: %[[coor:.*]] = hlfir.designate %[[a1_0]]#0{"p"}{{.*}} typeparams %{{.*}} {fortran_attrs = #fir.var_attrs} ! CHECK: fir.store {{.*}} to %[[coor]] allocate(a1_0%p(100)) ! CHECK: %[[a1_1_elem:.*]] = hlfir.designate %[[a1_1]]#0 (%{{.*}}) ! CHECK: %[[coor:.*]] = hlfir.designate %[[a1_1_elem]]{"p"}{{.*}} typeparams %{{.*}} {fortran_attrs = #fir.var_attrs} ! CHECK: fir.store {{.*}} to %[[coor]] allocate(a1_1(5)%p(100)) end subroutine ! CHECK-LABEL: func @_QMacompPallocate_def_char ! CHECK-SAME: (%[[a0_0_arg:.*]]: {{.*}}, %[[a1_0_arg:.*]]: {{.*}}, %[[a0_1_arg:.*]]: {{.*}}, %[[a1_1_arg:.*]]: {{.*}}) subroutine allocate_def_char(a0_0, a1_0, a0_1, a1_1) type(def_char_a0) :: a0_0, a0_1(100) type(def_char_a1) :: a1_0, a1_1(100) ! CHECK: %[[a0_0:.*]]:2 = hlfir.declare %[[a0_0_arg]]{{.*}}{uniq_name = "_QMacompFallocate_def_charEa0_0"} ! CHECK: %[[a0_1:.*]]:2 = hlfir.declare %[[a0_1_arg]](%{{.*}}){{.*}}{uniq_name = "_QMacompFallocate_def_charEa0_1"} ! CHECK: %[[a1_0:.*]]:2 = hlfir.declare %[[a1_0_arg]]{{.*}}{uniq_name = "_QMacompFallocate_def_charEa1_0"} ! CHECK: %[[a1_1:.*]]:2 = hlfir.declare %[[a1_1_arg]](%{{.*}}){{.*}}{uniq_name = "_QMacompFallocate_def_charEa1_1"} ! CHECK: %[[coor:.*]] = hlfir.designate %[[a0_0]]#0{"p"}{{.*}}{fortran_attrs = #fir.var_attrs} ! CHECK: fir.store {{.*}} to %[[coor]] allocate(character(18)::a0_0%p) ! CHECK: %[[a0_1_elem:.*]] = hlfir.designate %[[a0_1]]#0 (%{{.*}}) ! CHECK: %[[coor:.*]] = hlfir.designate %[[a0_1_elem]]{"p"}{{.*}}{fortran_attrs = #fir.var_attrs} ! CHECK: fir.store {{.*}} to %[[coor]] allocate(character(18)::a0_1(5)%p) ! CHECK: %[[coor:.*]] = hlfir.designate %[[a1_0]]#0{"p"}{{.*}}{fortran_attrs = #fir.var_attrs} ! CHECK: fir.store {{.*}} to %[[coor]] allocate(character(18)::a1_0%p(100)) ! CHECK: %[[a1_1_elem:.*]] = hlfir.designate %[[a1_1]]#0 (%{{.*}}) ! CHECK: %[[coor:.*]] = hlfir.designate %[[a1_1_elem]]{"p"}{{.*}}{fortran_attrs = #fir.var_attrs} ! CHECK: fir.store {{.*}} to %[[coor]] allocate(character(18)::a1_1(5)%p(100)) end subroutine ! ----------------------------------------------------------------------------- ! Test deallocation ! ----------------------------------------------------------------------------- ! CHECK-LABEL: func @_QMacompPdeallocate_real ! CHECK-SAME: (%[[a0_0_arg:.*]]: {{.*}}, %[[a1_0_arg:.*]]: {{.*}}, %[[a0_1_arg:.*]]: {{.*}}, %[[a1_1_arg:.*]]: {{.*}}) subroutine deallocate_real(a0_0, a1_0, a0_1, a1_1) type(real_a0) :: a0_0, a0_1(100) type(real_a1) :: a1_0, a1_1(100) ! CHECK: %[[a0_0:.*]]:2 = hlfir.declare %[[a0_0_arg]]{{.*}}{uniq_name = "_QMacompFdeallocate_realEa0_0"} ! CHECK: %[[a0_1:.*]]:2 = hlfir.declare %[[a0_1_arg]](%{{.*}}){{.*}}{uniq_name = "_QMacompFdeallocate_realEa0_1"} ! CHECK: %[[a1_0:.*]]:2 = hlfir.declare %[[a1_0_arg]]{{.*}}{uniq_name = "_QMacompFdeallocate_realEa1_0"} ! CHECK: %[[a1_1:.*]]:2 = hlfir.declare %[[a1_1_arg]](%{{.*}}){{.*}}{uniq_name = "_QMacompFdeallocate_realEa1_1"} ! CHECK: %[[coor:.*]] = hlfir.designate %[[a0_0]]#0{"p"}{{.*}}{fortran_attrs = #fir.var_attrs} ! CHECK: fir.store {{.*}} to %[[coor]] deallocate(a0_0%p) ! CHECK: %[[a0_1_elem:.*]] = hlfir.designate %[[a0_1]]#0 (%{{.*}}) ! CHECK: %[[coor:.*]] = hlfir.designate %[[a0_1_elem]]{"p"}{{.*}}{fortran_attrs = #fir.var_attrs} ! CHECK: fir.store {{.*}} to %[[coor]] deallocate(a0_1(5)%p) ! CHECK: %[[coor:.*]] = hlfir.designate %[[a1_0]]#0{"p"}{{.*}}{fortran_attrs = #fir.var_attrs} ! CHECK: fir.store {{.*}} to %[[coor]] deallocate(a1_0%p) ! CHECK: %[[a1_1_elem:.*]] = hlfir.designate %[[a1_1]]#0 (%{{.*}}) ! CHECK: %[[coor:.*]] = hlfir.designate %[[a1_1_elem]]{"p"}{{.*}}{fortran_attrs = #fir.var_attrs} ! CHECK: fir.store {{.*}} to %[[coor]] deallocate(a1_1(5)%p) end subroutine ! ----------------------------------------------------------------------------- ! Test a recursive derived type reference ! ----------------------------------------------------------------------------- ! CHECK: func @_QMacompPtest_recursive ! CHECK-SAME: (%[[xarg:.*]]: {{.*}}) subroutine test_recursive(x) type t integer :: i type(t), allocatable :: next end type type(t) :: x ! CHECK: %[[x:.*]]:2 = hlfir.declare %[[xarg]]{{.*}}{uniq_name = "_QMacompFtest_recursiveEx"} ! CHECK: %[[next1:.*]] = hlfir.designate %[[x]]#0{"next"}{{.*}}{fortran_attrs = #fir.var_attrs} ! CHECK: %[[nextBox1:.*]] = fir.load %[[next1]] ! CHECK: %[[next1addr:.*]] = fir.box_addr %[[nextBox1]] ! CHECK: %[[next2:.*]] = hlfir.designate %[[next1addr]]{"next"}{{.*}}{fortran_attrs = #fir.var_attrs} ! CHECK: %[[nextBox2:.*]] = fir.load %[[next2]] ! CHECK: %[[next2addr:.*]] = fir.box_addr %[[nextBox2]] ! CHECK: %[[next3:.*]] = hlfir.designate %[[next2addr]]{"next"}{{.*}}{fortran_attrs = #fir.var_attrs} ! CHECK: %[[nextBox3:.*]] = fir.load %[[next3]] ! CHECK: %[[next3addr:.*]] = fir.box_addr %[[nextBox3]] ! CHECK: %[[i:.*]] = hlfir.designate %[[next3addr]]{"i"} ! CHECK: %[[ival:.*]] = fir.load %[[i]] : !fir.ref print *, x%next%next%next%i end subroutine end module