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

pointer to equivalence:d array

Karanta__Antti
New Contributor I
337 Views
Hi!

When debugging a program crash due to access violation I came across a situation where a pointer points to a middle of an equivalence:d array with no target attribute (naturally, since equivalenced objects can't have the target attribute). The crash occurs when assigning via this pointer.

A code sample speaks more than a thousand words, so here's a somewhat minimal sample (which does not crash, but shows how the pointer and equivalence are mixed).

[fortran]! compile with
! ifort /check:pointer /RTCu /check:bound pointertest.f90
! or just 
! ifort pointertest.f90
!
! Having any of options /Qtrapuv , /Zi or /debug:full causes all the write statements in the end to print 1.0

module converter

    implicit none
    
contains 

    function convert( src ) result(ret)
       real*8, dimension(:), target :: src
       real*8, dimension(:), pointer :: ret
       ret => src
    end function
    
end module


program pointertest
    
    use converter

    implicit none

    integer*4, dimension( 14 ) :: my_i_array
    ! hcaing TARGET here (rightly) causes
    ! error #7725: An equivalence-object shall not have the TARGET attribute.
    real*8, dimension( size( my_i_array ) / 2 ) :: my_d_array
    equivalence ( my_i_array, my_d_array )
    real*8, dimension( : ), pointer :: my_real_ptr

    my_i_array = 0
    nullify( my_real_ptr )
    
    ! this (rightly) causes error #6796: 
    ! The variable must have the TARGET attribute or 
    !  be a subobject of an object with the TARGET attribute, or 
    ! it must have the POINTER attribute. 
    ! my_real_ptr => my_d_array( 2 : 7 )
    
    ! This compiles but should it? I now have a pointer the middle of an array, which breaks against at least
    ! the rule that an object pointed to must have TARGET attribute.
    !
    !   Pointer target  cannot be an array section with a vector subscript. (see Pointer assignment in ifort manual). 
    !   but is this equally true of an array section with non-vector subscript like used here?
    my_real_ptr => convert( my_d_array( 2 : 7 ) )

    my_real_ptr( 1 ) = 1.0
    
    write ( *, '(F)' ) my_d_array( 2 ) ! prints 0.0
    write ( *, '(F)' ) my_d_array( 2 ) ! prints 1.0  !!!!!!
    write ( *, '(F)' ) my_real_ptr( 1 ) ! prints 1.0
    write ( *, '(F)' ) my_d_array( 2 ) ! prints 1.0
    write ( *, '(F)' ) my_real_ptr( 1 ) ! prints 1.0

end program
[/fortran]

So my questions are: even though the compiler does not complain about this code, is this code ok and safe to use? It seems to break against the rule that pointed to object must have the target attribute.

It seems there is at least something weird going on here since printing the value of the same array value twice in a row produces different values (as seen in the comments in the above code and by running the code).

If the code above is not correct, is there any valid way to obtain a pointer to a section of an equivalence:d array?

Environment:

Intel Visual Fortran Compiler Professional for applications running on IA-32, Version 11.1 Build 20091130 Package ID: w_cprof_p_11.1.054
Windows 7 on x64

0 Kudos
1 Reply
mecej4
Honored Contributor III
337 Views
Of course the code is NOT safe to use.

You can get buggy code through the compilation process without seeing any error messages, but that feat does not relieve you of the responsibility for the bug. A "processor" may or may not implant checks for errors such as yours, but you cannot assume and the Fortran standard does not require any specific behavior.

The reason for seeing two different results from successive statements is that your bug is interacting with the compiler's optimizations. With optimization enabled, the compiled code need not have the same execution sequence as the Fortran code. It suffices that, for error-free input, the results from the optimized code are the same as if the statements were executed sequentially. With buggy input, especially with the compiler fooled as to which variables are aliased, the results of optimization can be confounding.
0 Kudos
Reply