blob: 413c7144f50433b2a481d9a0fc42344b398f57f5 [file] [edit]
! RUN: bbc -emit-fir %s -o - | FileCheck %s
! Test for component-wise initialization of derived types to avoid
! generating large, fully-initialized global templates.
module my_types
! Clean internal type: contains only allocatable and pointer components,
! without any default initialization.
type :: InnerClean
real, pointer :: p
real, allocatable :: arr(:)
end type InnerClean
! ============================================================================
! Test Case 1: Type meeting all criteria for component-wise init (Target)
! No arrays of derived types, no default initialization.
! ============================================================================
type :: TargetType
real, pointer :: q
real(8) :: uninit_buffer(80, 100)
type(InnerClean) :: nested_scalar
end type TargetType
! ============================================================================
! Test Case 2: Type triggering fallback A (contains an array of derived type)
! ============================================================================
type :: FallbackArrayType
type(InnerClean) :: nested_arr(10)
end type FallbackArrayType
! ============================================================================
! Test Case 3: Type triggering fallback B (contains default initialization)
! ============================================================================
type :: FallbackDefaultInitType
real, pointer :: p
integer :: flag = 999
end type FallbackDefaultInitType
! ============================================================================
! Test Case 4: Type triggering fallback C (contains default initialization)
! ============================================================================
type :: ProcPointerType
real, pointer :: p
procedure(), pointer, nopass :: pp => null()
end type ProcPointerType
! ============================================================================
! Test Case 5: Type with uninitialized procedure pointer.
! ============================================================================
type :: ProcPointerNoInitType
real, pointer :: p
procedure(), pointer, nopass :: pp
end type ProcPointerNoInitType
end module my_types
! ------------------------------------------------------------------------------
! Test 1: FIR generation for component-wise initialization
! ------------------------------------------------------------------------------
subroutine test_target()
use my_types
type(TargetType) :: my_var
call do_something_target(my_var)
end subroutine test_target
! CHECK-LABEL: func.func @_QPtest_target()
! CHECK: %[[ALLOCA:.*]] = fir.alloca !fir.type<_QMmy_typesTtargettype{{.*}}>
! CHECK: %[[MY_VAR:.*]] = fir.declare %[[ALLOCA]]
! CHECK: %[[Q_ADDR:.*]] = fir.coordinate_of %[[MY_VAR]], q
! CHECK: fir.store %{{.*}} to %[[Q_ADDR]]
! CHECK: %[[NESTED_ADDR:.*]] = fir.coordinate_of %[[MY_VAR]], nested_scalar
! CHECK: %[[P_ADDR:.*]] = fir.coordinate_of %[[NESTED_ADDR]], p
! CHECK: fir.store %{{.*}} to %[[P_ADDR]]
! CHECK: %[[ARR_ADDR:.*]] = fir.coordinate_of %[[NESTED_ADDR]], arr
! CHECK: fir.store %{{.*}} to %[[ARR_ADDR]]
! CHECK-NOT: fir.call @_FortranAInitialize
! CHECK-NOT: fir.global internal @_QQ_QMmy_typesTtargettype.DerivedInit
! ------------------------------------------------------------------------------
! Test 2: Fallback mechanism for arrays of derived types
! ------------------------------------------------------------------------------
subroutine test_fallback_array()
use my_types
type(FallbackArrayType) :: var_array
call do_something_array(var_array)
end subroutine test_fallback_array
! CHECK-LABEL: func.func @_QPtest_fallback_array()
! CHECK: %[[ALLOCA_ARR:.*]] = fir.alloca !fir.type<_QMmy_typesTfallbackarraytype{{.*}}>
! CHECK: %[[VAR_ARRAY:.*]] = fir.declare %[[ALLOCA_ARR]]
! CHECK: %[[GLOBAL_INIT_ARR:.*]] = fir.address_of(@_QQ_QMmy_typesTfallbackarraytype.DerivedInit)
! CHECK: fir.copy %[[GLOBAL_INIT_ARR]] to %[[VAR_ARRAY]]
! ------------------------------------------------------------------------------
! Test 3: Fallback mechanism for default initialization
! ------------------------------------------------------------------------------
subroutine test_fallback_default_init()
use my_types
type(FallbackDefaultInitType) :: var_default_init
call do_something_default_init(var_default_init)
end subroutine test_fallback_default_init
! CHECK-LABEL: func.func @_QPtest_fallback_default_init()
! CHECK: %[[ALLOCA_DEFAULT:.*]] = fir.alloca !fir.type<_QMmy_typesTfallbackdefaultinittype{{.*}}>
! CHECK: %[[VAR_DEFAULT:.*]] = fir.declare %[[ALLOCA_DEFAULT]]
! CHECK: %[[GLOBAL_INIT_DEFAULT:.*]] = fir.address_of(@_QQ_QMmy_typesTfallbackdefaultinittype.DerivedInit)
! CHECK: fir.copy %[[GLOBAL_INIT_DEFAULT]] to %[[VAR_DEFAULT]]
! ------------------------------------------------------------------------------
! Test 4: Procedure pointers
! Procedure pointers default initialized with '=> null()' trigger the
! default-initialization fallback safely.
! ------------------------------------------------------------------------------
subroutine test_proc_pointer()
use my_types
type(ProcPointerType) :: var_proc
call do_something_proc(var_proc)
end subroutine test_proc_pointer
! CHECK-LABEL: func.func @_QPtest_proc_pointer()
! CHECK: %[[ALLOCA:.*]] = fir.alloca !fir.type<_QMmy_typesTprocpointertype{{.*}}>
! CHECK: %[[VAR_DECL:.*]] = fir.declare %[[ALLOCA]] {{.*}}
! CHECK: %[[GLOBAL_INIT_PROC:.*]] = fir.address_of(@_QQ_QMmy_typesTprocpointertype.DerivedInit)
! CHECK: fir.copy %[[GLOBAL_INIT_PROC]] to %[[VAR_DECL]]
! ------------------------------------------------------------------------------
! Test 5: Procedure pointers
! Procedure pointers without default initialization should be initialized
! component-wise, without falling back to template copy initialization.
! ------------------------------------------------------------------------------
subroutine test_proc_pointer_no_init()
use my_types
type(ProcPointerNoInitType) :: var_proc
call do_something_proc_no_init(var_proc)
end subroutine test_proc_pointer_no_init
! CHECK-LABEL: func.func @_QPtest_proc_pointer_no_init()
! CHECK: %[[ALLOCA:.*]] = fir.alloca !fir.type<_QMmy_typesTprocpointernoinittype{{.*}}>
! CHECK: %[[VAR_DECL:.*]] = fir.declare %[[ALLOCA]] {{.*}}
! CHECK: %[[COORD_P:.*]] = fir.coordinate_of %[[VAR_DECL]], p
! CHECK: %[[NULL_P:.*]] = fir.zero_bits !fir.ptr<f32>
! CHECK: %[[BOX_P:.*]] = fir.embox %[[NULL_P]] : (!fir.ptr<f32>) -> !fir.box<!fir.ptr<f32>>
! CHECK: fir.store %[[BOX_P]] to %[[COORD_P]]
! CHECK: %[[COORD_PP:.*]] = fir.coordinate_of %[[VAR_DECL]], pp
! CHECK: %[[NULL_FUNC:.*]] = fir.zero_bits () -> ()
! CHECK: %[[BOX_PP:.*]] = fir.emboxproc %[[NULL_FUNC]] : (() -> ()) -> !fir.boxproc<() -> ()>
! CHECK: fir.store %[[BOX_PP]] to %[[COORD_PP]]
! CHECK-NOT: fir.copy