! RUN: bbc -emit-hlfir %s -o - | FileCheck %s ! Test lowering of pointers for allocate statements with source. ! CHECK-LABEL: func.func @_QPtest_pointer_scalar( ! CHECK-SAME: %[[ARG0:.*]]: !fir.ref ! CHECK: %[[DECL_A:.*]]:2 = hlfir.declare %[[ARG0]] ! CHECK: %[[ADDR_X1:.*]] = fir.address_of(@_QFtest_pointer_scalarEx1) ! CHECK: %[[DECL_X1:.*]]:2 = hlfir.declare %[[ADDR_X1]] ! CHECK: %[[ADDR_X2:.*]] = fir.address_of(@_QFtest_pointer_scalarEx2) ! CHECK: %[[DECL_X2:.*]]:2 = hlfir.declare %[[ADDR_X2]] ! CHECK: %[[FALSE:.*]] = arith.constant false ! CHECK: %[[ABSENT:.*]] = fir.absent !fir.box ! CHECK: %[[BOX_A:.*]] = fir.embox %[[DECL_A]]#0 ! CHECK: %[[BOX_X1:.*]] = fir.convert %[[DECL_X1]]#0 ! CHECK: %[[BOX_SOURCE:.*]] = fir.convert %[[BOX_A]] ! CHECK: fir.call @_FortranAPointerAllocateSource(%[[BOX_X1]], %[[BOX_SOURCE]], %[[FALSE]], %[[ABSENT]], %{{.*}}, %{{.*}}) ! CHECK: %[[BOX_X2:.*]] = fir.convert %[[DECL_X2]]#0 ! CHECK: %[[BOX_SOURCE_2:.*]] = fir.convert %[[BOX_A]] ! CHECK: fir.call @_FortranAPointerAllocateSource(%[[BOX_X2]], %[[BOX_SOURCE_2]], %[[FALSE]], %[[ABSENT]], %{{.*}}, %{{.*}}) subroutine test_pointer_scalar(a) real, save, pointer :: x1, x2 real :: a allocate(x1, x2, source = a) end ! CHECK-LABEL: func.func @_QPtest_pointer_2d_array( ! CHECK-SAME: %[[ARG0:.*]]: !fir.ref ! CHECK-SAME: %[[ARG1:.*]]: !fir.ref> ! CHECK: %[[DECL_N:.*]]:2 = hlfir.declare %[[ARG0]] ! CHECK: %[[X1:.*]] = fir.alloca !fir.box>> {{{.*}}uniq_name = "_QFtest_pointer_2d_arrayEx1"} ! CHECK: %[[DECL_X1:.*]]:2 = hlfir.declare %[[X1]] ! CHECK: %[[X2:.*]] = fir.alloca !fir.box>> {{{.*}}uniq_name = "_QFtest_pointer_2d_arrayEx2"} ! CHECK: %[[DECL_X2:.*]]:2 = hlfir.declare %[[X2]] ! CHECK: %[[X3:.*]] = fir.alloca !fir.box>> {{{.*}}uniq_name = "_QFtest_pointer_2d_arrayEx3"} ! CHECK: %[[DECL_X3:.*]]:2 = hlfir.declare %[[X3]] ! CHECK: %[[DECL_A:.*]]:2 = hlfir.declare %[[ARG1]] ! CHECK: %[[BOX_A:.*]] = fir.embox %[[DECL_A]]#1 ! CHECK: fir.call @_FortranAPointerSetBounds ! CHECK: fir.call @_FortranAPointerSetBounds ! CHECK: %[[BOX_X1:.*]] = fir.convert %[[DECL_X1]]#0 ! CHECK: %[[BOX_SOURCE:.*]] = fir.convert %[[BOX_A]] ! CHECK: fir.call @_FortranAPointerAllocateSource(%[[BOX_X1]], %[[BOX_SOURCE]], %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) ! CHECK: fir.call @_FortranAPointerSetBounds ! CHECK: fir.call @_FortranAPointerSetBounds ! CHECK: %[[BOX_X2:.*]] = fir.convert %[[DECL_X2]]#0 ! CHECK: %[[BOX_SOURCE_2:.*]] = fir.convert %[[BOX_A]] ! CHECK: fir.call @_FortranAPointerAllocateSource(%[[BOX_X2]], %[[BOX_SOURCE_2]], %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) ! CHECK: hlfir.designate %[[DECL_A]]#0 ! CHECK: fir.call @_FortranAPointerSetBounds ! CHECK: fir.call @_FortranAPointerSetBounds ! CHECK: %[[BOX_X3:.*]] = fir.convert %[[DECL_X3]]#0 ! CHECK: fir.call @_FortranAPointerAllocateSource(%[[BOX_X3]], %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) subroutine test_pointer_2d_array(n, a) integer, pointer :: x1(:,:), x2(:,:), x3(:,:) integer :: n, sss, a(n, n) allocate(x1, x2, source = a) allocate(x3, source = a(1:3:2, 2:3), stat=sss) end ! CHECK-LABEL: func.func @_QPtest_pointer_with_shapespec( ! CHECK-SAME: %[[ARG0:.*]]: !fir.ref{{.*}}%[[ARG1:.*]]: !fir.ref>{{.*}}%[[ARG2:.*]]: !fir.ref ! CHECK: %[[DECL_N:.*]]:2 = hlfir.declare %[[ARG0]] ! CHECK: %[[DECL_M:.*]]:2 = hlfir.declare %[[ARG2]] ! CHECK: %[[X1:.*]] = fir.alloca !fir.box>> ! CHECK: %[[DECL_X1:.*]]:2 = hlfir.declare %[[X1]] ! CHECK: %[[X2:.*]] = fir.alloca !fir.box>> ! CHECK: %[[DECL_X2:.*]]:2 = hlfir.declare %[[X2]] ! CHECK: %[[DECL_A:.*]]:2 = hlfir.declare %[[ARG1]] ! CHECK: %[[BOX_A:.*]] = fir.embox %[[DECL_A]]#1 ! CHECK: fir.call @_FortranAPointerSetBounds(%{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) ! CHECK: %[[BOX_X1:.*]] = fir.convert %[[DECL_X1]]#0 ! CHECK: %[[BOX_SOURCE:.*]] = fir.convert %[[BOX_A]] ! CHECK: fir.call @_FortranAPointerAllocateSource(%[[BOX_X1]], %[[BOX_SOURCE]], %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) ! CHECK: fir.call @_FortranAPointerSetBounds ! CHECK: %[[BOX_X2:.*]] = fir.convert %[[DECL_X2]]#0 ! CHECK: %[[BOX_SOURCE_2:.*]] = fir.convert %[[BOX_A]] ! CHECK: fir.call @_FortranAPointerAllocateSource(%[[BOX_X2]], %[[BOX_SOURCE_2]], %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) subroutine test_pointer_with_shapespec(n, a, m) integer, pointer :: x1(:), x2(:) integer :: n, m, a(n) allocate(x1(2:m), x2(n), source = a) end ! CHECK-LABEL: func.func @_QPtest_pointer_from_const( ! CHECK-SAME: %[[ARG0:.*]]: !fir.ref ! CHECK: %[[DECL_N:.*]]:2 = hlfir.declare %[[ARG0]] ! CHECK: %[[X1:.*]] = fir.alloca !fir.box>> ! CHECK: %[[DECL_X1:.*]]:2 = hlfir.declare %[[X1]] ! CHECK: %[[CONST_ADDR:.*]] = fir.address_of(@_QQro.5xi4.0) ! CHECK: %[[DECL_CONST:.*]]:2 = hlfir.declare %[[CONST_ADDR]] ! CHECK: %[[BOX_CONST:.*]] = fir.embox %[[DECL_CONST]]#0 ! CHECK: fir.call @_FortranAPointerSetBounds ! CHECK: %[[BOX_X1:.*]] = fir.convert %[[DECL_X1]]#0 ! CHECK: %[[BOX_SOURCE:.*]] = fir.convert %[[BOX_CONST]] ! CHECK: fir.call @_FortranAPointerAllocateSource(%[[BOX_X1]], %[[BOX_SOURCE]], %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) subroutine test_pointer_from_const(n, a) integer, pointer :: x1(:) integer :: n, a(n) allocate(x1, source = [1, 2, 3, 4, 5]) end ! CHECK-LABEL: func.func @_QPtest_pointer_chararray( ! CHECK-SAME: %[[ARG0:.*]]: !fir.ref ! CHECK-SAME: %[[ARG1:.*]]: !fir.boxchar<1> ! CHECK: %[[DECL_N:.*]]:2 = hlfir.declare %[[ARG0]] ! CHECK: %[[X1:.*]] = fir.alloca !fir.box>>> ! CHECK: %[[DECL_X1:.*]]:2 = hlfir.declare %[[X1]] ! CHECK: %[[UNBOX:.*]]:2 = fir.unboxchar %[[ARG1]] ! CHECK: %[[CONV:.*]] = fir.convert %[[UNBOX]]#0 ! CHECK: %[[DECL_A:.*]]:2 = hlfir.declare %[[CONV]] ! CHECK: %[[BOX_A:.*]] = fir.embox %[[DECL_A]]#1 ! CHECK: fir.call @_FortranAPointerSetBounds ! CHECK: %[[BOX_X1:.*]] = fir.convert %[[DECL_X1]]#0 ! CHECK: %[[BOX_SOURCE:.*]] = fir.convert %[[BOX_A]] ! CHECK: fir.call @_FortranAPointerAllocateSource(%[[BOX_X1]], %[[BOX_SOURCE]], %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) subroutine test_pointer_chararray(n, a) character(4), pointer :: x1(:) integer :: n character(*) :: a(n) allocate(x1, source = a) end ! CHECK-LABEL: func.func @_QPtest_pointer_char( ! CHECK-SAME: %[[ARG0:.*]]: !fir.ref ! CHECK-SAME: %[[ARG1:.*]]: !fir.boxchar<1> ! CHECK: %[[UNBOX:.*]]:2 = fir.unboxchar %[[ARG1]] ! CHECK: %[[DECL_A:.*]]:2 = hlfir.declare %[[UNBOX]]#0 ! CHECK: %[[DECL_N:.*]]:2 = hlfir.declare %[[ARG0]] ! CHECK: %[[X1:.*]] = fir.alloca !fir.box>> ! CHECK: %[[DECL_X1:.*]]:2 = hlfir.declare %[[X1]] ! CHECK: %[[BOX_A:.*]] = fir.embox %[[DECL_A]]#1 ! CHECK: fir.call @_FortranAPointerNullifyCharacter ! CHECK: %[[BOX_X1:.*]] = fir.convert %[[DECL_X1]]#0 ! CHECK: %[[BOX_SOURCE:.*]] = fir.convert %[[BOX_A]] ! CHECK: fir.call @_FortranAPointerAllocateSource(%[[BOX_X1]], %[[BOX_SOURCE]], %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) subroutine test_pointer_char(n, a) character(:), pointer :: x1 integer :: n character(*) :: a allocate(x1, source = a) end ! CHECK-LABEL: func.func @_QPtest_pointer_derived_type( ! CHECK-SAME: %[[ARG0:.*]]: !fir.ref>>}>>>>> ! CHECK: %[[DECL_Y:.*]]:2 = hlfir.declare %[[ARG0]] ! CHECK: %[[Z:.*]] = fir.alloca !fir.box>>}>>>> ! CHECK: %[[DECL_Z:.*]]:2 = hlfir.declare %[[Z]] ! CHECK: %[[LOAD_Y:.*]] = fir.load %[[DECL_Y]]#0 ! CHECK: fir.call @_FortranAPointerSetBounds ! CHECK: %[[BOX_Z:.*]] = fir.convert %[[DECL_Z]]#0 ! CHECK: %[[BOX_SOURCE:.*]] = fir.convert %[[LOAD_Y]] ! CHECK: fir.call @_FortranAPointerAllocateSource(%[[BOX_Z]], %[[BOX_SOURCE]], %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) subroutine test_pointer_derived_type(y) type t integer, pointer :: x(:) end type type(t), pointer :: z(:), y(:) allocate(z, source=y) end