Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
28457 Discussions

Strange behavior of allocatable array with internal procedure

Wolf_W_
New Contributor I
306 Views

Greetings,

i got a problem with an allocatable array, that gets resized in an subroutine. Without the internal function "testArguments", the array has the expected size of 40 at the end. If "testArguments" is defined (no matter if it is called), the array stays the same size in the main program. "array" seems to become a local variable to "testArguments", instead of a reference to "foo_array".

It it doesn't matter if "testArguments" is a function or subroutine.

It works (any of those points):
- when the array is passed as argument to "testArguments".
- compiler-option /C is used
- optimizations are turned off (/Od)
- "array" is not used in "testArguments"
- "STRANGE_BLOCK" is present

This happens with compilers 15.5 and 16.1 (32bit and 64bit) on windows.

module TEST_MOD
  implicit none
contains

!-------------------------------------------------------------------------------
  subroutine foo
    integer, allocatable :: foo_array(:)

    allocate(foo_array(10))

    call extendArray(foo_array)
    call extendArray(foo_array)
    call extendArray(foo_array)

    ! It works, if this block exists
!    STRANGE_BLOCK : block
!      write(*,*)size(foo_array)
!    end block STRANGE_BLOCK

    write(*,*) 'Expected:'
    write(*,*) 40

    write(*,*) 'Got:'
    write(*,*) size(foo_array, dim=1)

  end subroutine

!-------------------------------------------------------------------------------
  subroutine extendArray(array)
    integer, allocatable, intent(inout) :: array(:)
    integer :: n
  ! ========================

    ! Doesn't matter if called or not.
!    if(.NOT. testArguments()) return

    n = size(array,dim=1)+10
    deallocate(array)
    allocate(array(n))

    write(*,*) size(array,dim=1)

    contains! -------------------------------------------------------------

      ! does not work:
      logical function testArguments() result(valid)
        valid = allocated(array)
      end function testArguments

      ! works: (independent of used arg-name)
!      logical function testArguments(array) result(valid)
!        integer, allocatable, intent(inout) :: array(:)
!        valid = allocated(array)
!      end function testArguments

  end subroutine extendArray

end module TEST_MOD

!===============================================================================

program main
  use TEST_MOD
  call foo()
end program

Wolf

0 Kudos
7 Replies
mecej4
Honored Contributor III
306 Views

Please see if turning off optimization (using option /Od) makes the bug go away (as it seems to on Linux).

0 Kudos
Wolf_W_
New Contributor I
306 Views

yes, it goes away with /Od (as stated in original post - i should have been more specific)

0 Kudos
mecej4
Honored Contributor III
306 Views

My lapse, I overlooked that line.

It is typical of optimizer bugs that they can be made dormant by any number of slight changes to the code, and can even be Heisenbugs. Thus, when those changes are described in detail, one tends to be side-tracked into analyzing those changes as to their specifics.

0 Kudos
Wolf_W_
New Contributor I
306 Views

Thanks for introducing me to the term "Heisenbug" - i like that.

It actually confused me a lot, as it went away, when i wrote out the array in the block-part. I tried turning off the optimization only when i worked on the reproducer.

0 Kudos
Steven_L_Intel1
Employee
306 Views

Thanks, we'll take a look.

0 Kudos
Steven_L_Intel1
Employee
306 Views

Thanks for the nice test case and the observations. This has been escalated to the developers as issue DPD200380881. I will update this thread when I have news.

0 Kudos
Steven_L_Intel1
Employee
306 Views

This problem has been fixed. I expect the fix to appear in the 16.0.4 update as well as the 17.0 product release.

0 Kudos
Reply