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.