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.