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

Operator overloading side-effects when using parameterized derived types

jwmwalrus
New Contributor I
361 Views

Hi.

I know this is the less popular feature in the history of Fortran, but I somehow see its merits.

The following code

module itemmod
    use ISO_FORTRAN_ENV

    implicit none
    private
    save

    type, public :: item(ilen, k)
        integer, len :: ilen = 0
        integer, kind :: k = real32
        real(k) :: val = 0
        integer :: delta(2) = 0
    end type

    interface operator(+)
        module procedure item_PLUS_item
    end interface
    public operator(+)

    interface operator(*)
        module procedure scalar_TIMES_item
    end interface
    public operator(*)

    type(item(1)), parameter, public :: group1 = item(1)(1., [1, 0])
    type(item(2)), parameter, public :: group2 = item(2)(1., [0, 1])

contains
    subroutine assert_same_group(lhs, rhs)
        type(item(*)), intent(in) :: lhs
        type(item(*)), intent(in) :: rhs
        print*,'assert_lhs=',lhs, ',ilen=',lhs%ilen
        print*,'assert_rhs=',rhs, ',ilen=',rhs%ilen
        if (lhs%ilen /= rhs%ilen) error stop 'ilen mismatch'
        if (.not. all(lhs%delta == rhs%delta)) error stop 'delta mismatch'
    end subroutine

    function item_PLUS_item(lhs, rhs) result(res)
        type(item(*)), intent(in) :: lhs
        type(item(*)), intent(in) :: rhs
        type(item(lhs%ilen)) :: res
        call assert_same_group(lhs, rhs)
        res%val = lhs%val + rhs%val
        res%delta = lhs%delta
    end function

    pure function scalar_TIMES_item(lhs, rhs) result(res)
        real, intent(in) :: lhs
        type(item(*)), intent(in) :: rhs
        type(item(rhs%ilen)) :: res
        res%val = lhs * rhs%val
        res%delta = rhs%delta
    end function
end module itemmod

use ISO_FORTRAN_ENV
use itemmod

implicit none

type(item(1)) :: x, v
type(item(2)) :: y, w

print*,'group1=',group1,', ilen=',group1%ilen
print*,'group2=',group2,' ilen=',group2%ilen

x = 5. * group1
print*,'x=',x, ', ilen=',x%ilen
y = 5. * group2
print*,'y=',y,', ilen=',y%ilen
print*, x+y

! v = group1
! print*,'v=',v, ', ilen=',v%ilen
! w = group2
! print*,'w=',w,', ilen=',w%ilen
! print*, v+w

end

Fails to pass the correct ilen parameter when used in the binary (plus operator) expression at line 71:

$ ifx -V -g -O0 items.f90 && ./a.out 
Intel(R) Fortran Compiler for applications running on Intel(R) 64, Version 2024.1.0 Build 20240308
Copyright (C) 1985-2024 Intel Corporation. All rights reserved.

 Intel(R) Fortran 24.0-1472.3
GNU ld (GNU Binutils for Debian) 2.42
 group1=  0.0000000E+00           1           0 , ilen=           1
 group2=  0.0000000E+00           0           1  ilen=           2
 x=  0.0000000E+00           1           0 , ilen=           1
 y=  0.0000000E+00           0           1 , ilen=           2
 assert_lhs=  0.0000000E+00           1           0 ,ilen=           1
 assert_rhs=  0.0000000E+00           0           1 ,ilen=           1
delta mismatch

The assert_same_group subroutine call should have stopped with 'ilen mismatch', but the ilen value for the rhs argument is somehow lost during invocation (and the value shown is not even the default one).

If I comment out lines 67-71 and uncomment lines 73-77, I get correct results for the assert_same_group call, at the expense of not using the overloaded operator(*) :

$ ifx -V -g -O0 items.f90 && ./a.out 
Intel(R) Fortran Compiler for applications running on Intel(R) 64, Version 2024.1.0 Build 20240308
Copyright (C) 1985-2024 Intel Corporation. All rights reserved.

 Intel(R) Fortran 24.0-1472.3
GNU ld (GNU Binutils for Debian) 2.42
 group1=  0.0000000E+00           1           0 , ilen=           1
 group2=  0.0000000E+00           0           1  ilen=           2
 v=  0.0000000E+00           1           0 , ilen=           1
 w=  0.0000000E+00           0           1 , ilen=           2
 assert_lhs=  0.0000000E+00           1           0 ,ilen=           1
 assert_rhs=  0.0000000E+00           0           1 ,ilen=           2
ilen mismatch

 

And also, in all the cases, with ifx, the constructor at lines 25-26 is misbehaving (i.e., not assigning anything to val). With ifort, val is assigned correctly.

 

 

 

 

1 Reply
Barbara_P_Intel
Moderator
314 Views

Thanks for reporting this. I filed a bug report, CMPLRLLVM-57787.

We'll let you know when the issues are fixed.

 

0 Kudos
Reply