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

ifort 19.0.3: Defined Assignemt broken?

Schwab__Jonas
Beginner
440 Views

In ifort version 19.0.3, a defined assignment of an object seems to be broken. An assignment of the sort "b(i) = a(i)" seems to be behaving like "b(i) = a(1)". An explicit call to the subroutine works, though.

The following code:

MODULE test_mod
    IMPLICIT NONE
    
    TYPE obj
        Integer :: i
        CONTAINS
            PROCEDURE :: assign => assign_obj
            GENERIC :: ASSIGNMENT(=) => assign
    END TYPE obj
    
    ! Replacing the Type-Bound Procedure by the following interface leads to the same results
    ! INTERFACE ASSIGNMENT(=)
    !     PROCEDURE assign_obj
    ! END INTERFACE
    
    CONTAINS
    
    SUBROUTINE assign_obj(this, src)
        IMPLICIT NONE
        CLASS(obj), INTENT(INOUT) :: this
        CLASS(obj), INTENT(IN)    :: src
        print *, src%i
        this%i = src%i
    END SUBROUTINE assign_obj
    
end module test_mod


program test
    use test_mod
    implicit none
    
    CLASS(obj), DIMENSION(:), ALLOCATABLE :: a, b
    Integer :: i, N
    
    N = 5
    
    ALLOCATE( a(N), b(N) )
    do i=1, N
        a(i)%i = i
    enddo
    
    do i=1, N
        ! The following assigment should do the same as each of the other two commented out
        ! lines below that, but ifort 19.0.3 seems to be doing somethin like "b(i) = a(1)"
        b(i) = a(i)
        ! call b(i)%assign( a(i) )
        ! call assign_obj( b(i), a(i) )
    enddo
    
    print*, "test"
    
    do i=1, N
        print*, b(i)%i
    enddo

end program

After compilation with ifort 17.0.1, ifort 18.0.2, gfortran 6.3.0 , gfortran 7.3.0and pgfortran 18.4-0 and execution produces, as expected:

           1
           2
           3
           4
           5
 test
           1
           2
           3
           4
           5

 

After compilation with ifort 19.0.3 and execution produces

           1
           1
           1
           1
           1
 test
           1
           1
           1
           1
           1

 Notably, replacing "b(i) = a(i)" by "call b(i)%assign( a(i) )" or "call assign_obj( b(i), a(i) )" works as expected.

I believe I'm working within the specifications of this, this and this. So it seems to me like a compile bug. What do you think?

0 Kudos
2 Replies
Juergen_R_R
Valued Contributor II
440 Views

Hi Jonas,

very interesting piece of code. Your assigment is _not_ defined elemental, and you also don't apply it to an array of types obj, but only elementwise. However, defining your assigment as elemental subroutine (and removing the print statement within) is a workaround that also makes ifort 19 produce the desired result. To me this looks indeed like a bug in ifort v19, and you might want to report this in the Intel Support Center to check with them. gfortran, nagfor, pgi and older versions of ifort produce the desired result.

Cheers,

    J

0 Kudos
FortranFan
Honored Contributor III
440 Views

Juergen R. wrote:

.. you might want to report this in the Intel Support Center ..

@Schwab, Jonas:

As suggested above, it will be very useful to Intel Fortran users if you can submit your nice case in the original post as a support request with Intel.  Defined assignments with polymorphic objects is a very valuable feature in the Fortran standard and it's very important the Intel Fortran compiler gets this right.

In addition to when the defined assignment is marked ELEMENTAL, the results are as expected with Intel 19.0.3 also when the second argument (the RHS) in the bound procedure for assignment is not polymorphic (type(obj) vs class(obj)) and when the objects in your test main are not polymorphic (type(obj), .. :: a, b).

So one should expect the Intel compiler team to be keen to look at this likely regression in update 3 of their product.

0 Kudos
Reply