In this minimal example, is it allowed to pass the optional dummy argument y
of test_wrapper
that may not be present
as actual argument for the corresponding optional dummy argument y
of test
?
program main
implicit none
real :: x = 5.0
call test_wrapper(x)
contains
subroutine test_wrapper(x, y)
implicit none
real, intent(in) :: x
real, dimension(:), intent(out), optional :: y
call test(x, y)
end subroutine test_wrapper
subroutine test(x, y)
implicit none
real, intent(in) :: x
real, dimension(:), intent(out), optional :: y
if (present(y)) then
y = x
end if
end subroutine test
end program
UndefinedBehaviourSanitizer raises an error, indicating that it is not: https://godbolt.org/z/nKj1h6G9r
In this Fortran standards document (Section 15.5.2.12, "Argument presence and restrictions on arguments not present" on page 311) it says:
- An optional dummy argument that is not present is subject to the following restrictions.
- If it is a data object, it shall not be referenced or be defined. If it is of a type that has default initialization, the initialization has no effect.
- [...]
- [...]
- [...]
- A designator with it as the base object and with one or more subobject selectors shall not be supplied as an actual argument.
- [...]
- If it is a pointer, it shall not be allocated, deallocated, nullified, pointerassigned, or supplied as an actual argument corresponding to an optional nonpointer dummy argument.
- If it is allocatable, it shall not be allocated, deallocated, or supplied as an actual argument corresponding to an optional nonallocatable dummy argument.
- [...]
- Except as noted in the list above, it may be supplied as an actual argument corresponding to an optional dummy argument, which is then also considered not to be present.
I'm struggling to read the standardese in that list, so perhaps one of the items in it that I don't fully understand prohibits this for assumed-shape arrays? But to my mind, none of the restrictions would apply for this case.
But interestingly, UBSan only seems to raise the error if using dimension(:)
, i.e. if y
is an assumed-shape array. Anything else like dimension(2)
, dimension(n)
with an added size parameter n
, allocatable
, pointer
or nothing do not seem to trigger UBSan.