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

Ifort selects wrong interface for overloaded intrinsic operator

Harald1
New Contributor II
477 Views

Hello,

the following code is miscompiled by ifort/ifx:

module m
  implicit none
  interface operator (==)
     module procedure star_eq
  end interface
contains
  function star_eq(a, b)
    class(*), intent(in) :: a, b
    integer              :: star_eq
    star_eq = 42
  end function star_eq
end

program p
   use m
   implicit none
   character :: c = 'a'
   print *, ('a' == 'a') ! expect: T
   print *, ('a' ==  c ) ! expect: T
   print *, ( c  ==  c ) ! expect: T
end

 I get here:

% ifx -what ifort-wrong-interface.f90 && ./a.out 
 Intel(R) Fortran 23.0-1769.01
          42
          42
          42

 Note that NAG prints 3 lines with "T", as expected.

 

Ifort/ifx appears to ignore that in the present situation the compiler must choose the intrinsic

comparison operator since the arguments are consistent with F2018:10.1.5.

 

0 Kudos
2 Replies
jimdempseyatthecove
Honored Contributor III
457 Views

perhaps this is one of the few cases where NAG is wrong.

module c
    contains
    
    function character_eq_character(a,b)
        character(len=*), intent(in) :: a, b
        logical :: character_eq_character
        character_eq_character = (a==b)
    end function character_eq_character
    
    function integer_eq_integer(a,b)
        integer, intent(in) :: a, b
        logical :: integer_eq_integer
        integer_eq_integer = (a==b)
    end function integer_eq_integer
end module c
    
module m
  implicit none
  interface operator (==)
     module procedure star_eq
  end interface
contains
  function star_eq(a, b)
    use c
    class(*), intent(in) :: a, b
    logical              :: star_eq
    select type(a)
    class is (character(len=*))
        select type(b)
        class is (character(len=*))
            star_eq = character_eq_character(a,b)
        class default
            star_eq = .false.
        end select
    class is (integer)
        select type(b)
        class is (integer)
            star_eq = integer_eq_integer(a,b)
        class default
            star_eq = .false.
        end select
    
    class default
    star_eq = .false.
    end select
    
  end function star_eq
end

program p
   use m
   implicit none
   character :: c = 'a'
   print *, ('a' == 'a') ! expect: T
   print *, ('a' ==  c ) ! expect: T
   print *, ( c  ==  c ) ! expect: T
   print *, ('a' == 'b') ! expect: F
   print *, ('a' == 1)   ! expect: F
   print *, (1 == 2)     ! expect: F
   print *, (1 == 1)     ! expect: T
end
output:
 T
 T
 T
 F
 F
 F
 T

Jim Dempsey

0 Kudos
jimdempseyatthecove
Honored Contributor III
457 Views

You can fill in the other permutations.

 

Jim Dempsey

0 Kudos
Reply