This is a follow-up question to the previous question
The difference here is that the optional argument is an array. Nevertheless, this is NOT a duplicate question as this question adds additional aspect such as different compiler behavior/failure when the optional argument is an array as opposed to a scalar.
main.F90
program main
  use my_module
  real(8) :: a
  real(8), allocatable, dimension(:,:) :: b
  a = 1.3 
  allocate(b(2,2))
  b(1,1)=1.0
  b(1,2)=2.0
  b(2,1)=3.0
  b(2,2)=4.0
  !call my_subroutine1(a, b)  ! case 1
  !call my_subroutine2(a, b)  ! case 2
  !call my_subroutine1(a)     ! case 3
  call my_subroutine2(a)     ! case 4
end program main
test.F90
module my_module
contains
  subroutine my_subroutine1(a, b)
    class(*), intent(in) :: a
    class(*), intent(in), optional, dimension(:,:) :: b
    select type (a) 
    type is (real(4))
      print*, 'real 4 a (my_subroutine1): ', a
    type is (real(8))
      print*, 'real 8 a (my_subroutine1): ', a
    end select
    if (present(b)) then
      print*, 'b is present in subroutine1'
      select type (b) 
      type is (real(4))
        print*, 'real 4 b: ', b
      type is (real(8))
        print*, 'real 8 b: ', b
      end select
    else
    end if
    call my_subroutine3(a, b)
  end subroutine my_subroutine1
  subroutine my_subroutine2(a, b)
    real(8), intent(in) :: a
    real(8), intent(in), optional, dimension(:,:) :: b
    print*, 'real 8 a (my_subroutine2): ', a
    if (present(b)) then
      print*, 'b is present in subroutine2'
      print*, 'real 8 b: ', b
    else
    end if
    call my_subroutine3(a, b)
  end subroutine my_subroutine2
  subroutine my_subroutine3(a, b)
    class(*), intent(in) :: a
    class(*), intent(in), optional, dimension(:,:) :: b
    select type (a) 
    type is (real(4))
      print*, 'real 4 a (my_subroutine3): ', a
    type is (real(8))
      print*, 'real 8 a (my_subroutine3): ', a
    end select
    if (present(b)) then
      print*, 'b is present in subroutine3'
      select type (b) 
      type is (real(4))
        print*, 'real 4 b: ', b
      type is (real(8))
        print*, 'real 8 b: ', b
      end select
    end if
  end subroutine my_subroutine3
end module my_module
The first 3 subroutine calls (cases 1, 2 and 3) in main.F90 behave as expected. However, when case 4 is called (call my_subroutine2(a)), segmentation fault occurs:
 real 8 a (my_subroutine2):    1.29999995231628     
forrtl: severe (174): SIGSEGV, segmentation fault occurred
Image              PC                Routine            Line        Source             
a.out              000000000040EB4A  Unknown               Unknown  Unknown
libpthread-2.17.s  00007F5358615630  Unknown               Unknown  Unknown
a.out              00000000004059F0  Unknown               Unknown  Unknown
a.out              00000000004084AA  Unknown               Unknown  Unknown
a.out              00000000004038A2  Unknown               Unknown  Unknown
libc-2.17.so       00007F535825A555  __libc_start_main     Unknown  Unknown
a.out              00000000004037A9  Unknown               Unknown  Unknown
Intel compiler versions 18.0.5.274, 19.0.5.281, 2020.2, and 2021.3.0 all failed. However, with Gnu/9.2.0, it behaves as expected:
 real 8 a (my_subroutine2):    1.2999999523162842     
 real 8 a (my_subroutine3):    1.2999999523162842  
So, I am thinking this is an Intel bug. NOW, comment out in main.F90 the allocation of b:
  !allocate(b(2,2))  
  !b(1,1)=1.0                                 
  !b(1,2)=2.0        
  !b(2,1)=3.0                                 
  !b(2,2)=4.0 
Even though b is not allocated, subroutines should not have a problem since b is an optional argument.
Gnu/9.2.0 now gives segfault for case 4:
Program received signal SIGSEGV: Segmentation fault - invalid memory reference.
Backtrace for this error:
#0  0x7f2c313863ff in ???
#1  0x7f2c320bd611 in get_float_string
    at /tmp/Role.Apps/spack-stage/spack-stage-gcc-9.2.0-wqdecm4rkyyhejagxwmnabt6lscgm45d/spack-src/libgfortran/io/write_float.def:1070
#2  0x7f2c320bfdd5 in list_formatted_write_scalar
    at /tmp/Role.Apps/spack-stage/spack-stage-gcc-9.2.0-wqdecm4rkyyhejagxwmnabt6lscgm45d/spack-src/libgfortran/io/write.c:1879
#3  0x7f2c320b3365 in wrap_scalar_transfer
    at /tmp/Role.Apps/spack-stage/spack-stage-gcc-9.2.0-wqdecm4rkyyhejagxwmnabt6lscgm45d/spack-src/libgfortran/io/transfer.c:2369
#4  0x7f2c320b3365 in wrap_scalar_transfer
    at /tmp/Role.Apps/spack-stage/spack-stage-gcc-9.2.0-wqdecm4rkyyhejagxwmnabt6lscgm45d/spack-src/libgfortran/io/transfer.c:2346
#5  0x40195b in __my_module_MOD_my_subroutine3
    at /scratch2/NCEPDEV/stmp1/Minsuk.Ji/Fortran/03/test.F90:62
#6  0x402142 in __my_module_MOD_my_subroutine2
    at /scratch2/NCEPDEV/stmp1/Minsuk.Ji/Fortran/03/test.F90:41
#7  0x40354f in MAIN__
    at /scratch2/NCEPDEV/stmp1/Minsuk.Ji/Fortran/03/main.F90:18
#8  0x40358f in main
    at /scratch2/NCEPDEV/stmp1/Minsuk.Ji/Fortran/03/main.F90:2
Segmentation fault
Even more confusingly, Intel's now give segfault for case 2 in addition to case 4.