module test

type t
 contains
  final :: final_scalar_t,finalizer1,finalizer2,finalizer3
end type t

type, extends(t) :: t1
 contains
  final :: final_scalar_t1
end type t1

type a1
 integer :: i
 contains
  final :: finalizer_a1
end type a1

type a2
 integer :: k
 contains
  final :: finalizer_a2
end type a2

type, extends(t1) :: t2
 type(a1) :: aaa
 type(a2) :: aaa2
 class(t), allocatable :: ttt
 contains
  final :: final_scalar, finalizer1t2
end type t2

contains
 subroutine finalizer_a1(aa)
  type(a1), intent(in) :: aa
  write(*,*) 'A1 - i='
 end subroutine finalizer_a1
 subroutine finalizer_a2(aa)
  type(a2), intent(in) :: aa
  write(*,*) 'A2 - k='
 end subroutine finalizer_a2
 subroutine final_scalar(t0)
  type(t2),intent(in) :: t0
  write(*,*) 'rank 0'
 end subroutine final_scalar
 subroutine final_scalar_t(t0)
  type(t), intent(in) :: t0
  write(*,*) 'rank 00'
 end subroutine final_scalar_t
 subroutine final_scalar_t1(t0)
  type(t1), intent(in) :: t0
  write(*,*) 'rank 0 su t1'
 end subroutine final_scalar_t1
 subroutine finalizer1(t1)
  type(t) :: t1(:)
  write(*,*) 'rank 1'
 end subroutine finalizer1
 subroutine finalizer1t2(tt2)
  type(t2) :: tt2(:)
  write(*,*) 'rank 1 t2'
 end subroutine finalizer1t2
 subroutine finalizer2(t2)
  type(t) :: t2(:,:)
  write(*,*) 'rank 2'
 end subroutine finalizer2
 subroutine finalizer3(t3)
  type(t) :: t3(:,:,:)
  write(*,*) 'rank 3'
 end subroutine finalizer3

end module test

use test
implicit none

class(t), allocatable :: tt

allocate(t2 :: tt)
select type (tt)
 type is (t2)
  allocate(tt%ttt)
end select
deallocate(tt)

end
