main.F90
program main
  use my_module
  real(8) :: a, b
  a = 1.3
  b = 2.4
  call my_subroutine1(a)
  !call my_subroutine2(a)
end program main
test.F90
module my_module
contains
  subroutine my_subroutine1(a, b)
    class(*), intent(in) :: a
    class(*), intent(in), optional :: 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 :: 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 :: 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
When main calls my_subroutine1(a), output is
 real 8 a (my_subroutine1):    1.29999995231628     
 real 8 a (my_subroutine3):    1.29999995231628 
However, when main calls my_subroutine2(a), output is
 real 8 a (my_subroutine2):    1.29999995231628     
 real 8 a (my_subroutine3):    1.29999995231628     
 b is present in subroutine3
forrtl: severe (408): fort: (7): Attempt to use pointer B when it is not associated with a target
Image              PC                Routine            Line        Source             
a.out              00000000004072A0  Unknown               Unknown  Unknown
a.out              0000000000404897  my_module_mp_my_s          62  test.F90
a.out              0000000000403CA2  my_module_mp_my_s          41  test.F90
a.out              0000000000404984  MAIN__                     10  main.F90
a.out              0000000000402B9E  Unknown               Unknown  Unknown
libc-2.17.so       00007F05EDED2555  __libc_start_main     Unknown  Unknown
a.out              0000000000402AA9  Unknown               Unknown  Unknown
In the second case (calling my_subroutine2), why does my_subroutine3 think the optional argument is present?
I understand that I can do something like this in my_subroutine2
if (present(b)) then
  call my_subroutine3(a,b)
else
  call my_subroutine3(a)
end if
but with all b's being an optional dummy argument in all 3 subroutines, this is not required as supported by my_subroutine1.
Is using class(*) variable as optional dummy argument causing this problem? If that's the case, why does main calling my_subroutine1 work without an error?