I’m encountering a situation where optimizer inlining produces a different result because of conflict with intent(IN). Consider the following example code:
module mymod
implicit none
contains
subroutine mysub(i)
integer, intent(IN) :: i
call setval(i)
end subroutine mysub
subroutine setval(i)
integer :: i
! -- i may be set here because setval does not use intent(IN)
i = 20
end subroutine setval
end module mymod
program main
use mymod, only : mysub
implicit none
integer :: i
i = 10
write(*,*) 'before sub: ', i
call mysub(i)
write(*,*) 'after sub: ', i
end program main
With optimizations off, the code produces:
% pgfortran -O0 test_intent.f90 && ./a.out
before sub: 10
after sub: 20
With full optimizations, including inlining which I suspect is the culprit, the code produces:
% pgfortran -O3 test_intent.f90 && ./a.out
before sub: 10
after sub: 10
Without any inlining, setval is able to set i because intent(IN) is only declared within mysub. With optimizations on, though, i is being set within a scope where i is readonly. So I guess the compiler is silently deciding not to set it?
I’m not certain what expected behaviour is in this case. It’s disconcerting to me that -O3 and -O0 give different results. I also would have liked to see a warning about editing a read-only variable when inlining is performed - silently changing the behaviour seems like an error to me. Intel and gfortran both produce the same results (10 and 20) regardless of optimization level.
What is expected behaviour in this case? Is there any way for me to see a warning about not setting i? My tests were conducted on PGI 15.5.