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

Ambiguous generic interface: ifort 13.1.0 vs. ifort 19.1.1.217 --> warning #6738 changes to error #5286

Sabielny__Michael
665 Views

So I have this legacy code that compiles with ifort 13.1.0 with a warning,  but which generates an error in ifort 19.1.1.217. I've boiled down the problem to a small minimum working (or should I say: failing) example. I personally find this code at least weird, but it is not mine; however I took over the maintainer roll:

module mwe
  interface scalprod
     module procedure scalprod_vE
     module procedure scalprod_Ev
  end interface scalprod

  integer,parameter :: dp = kind(0.0d0)

  type :: ThreeVec
     real(dp), dimension(3) :: pos
  end type ThreeVec

  type :: cField
     complex(dp), dimension(3) :: c
  end type cField

  private :: scalprod_vE, scalprod_Ev

contains

  complex(dp) function scalprod_vE(v, E)
    type(ThreeVec), intent(in) :: v
    type(cField), intent(in) :: E
    ! ---
    scalprod_vE = v%pos(1) * E%c(1) + v%pos(2) * E%c(2) + v%pos(3) * E%c(3)
  end function scalprod_vE

  complex(dp) function scalprod_Ev(E, v)
    type(ThreeVec), intent(in) :: v
    type(cField), intent(in) :: E
    ! ---
    scalprod_Ev = scalprod_vE(v, E)
  end function scalprod_Ev

end module mwe

With the old compiler I still get a warning - however compilation succeedes with return value 0:

[user@host trunk]$ <path_to_old_compiler>/opt/intel/composerxe/bin/ifort --version
ifort (IFORT) 13.1.0 20130121
Intel Corporation.  All rights reserved. 1985-2013 NEC Corporation.  All rights reserved.

[user@host trunk]$ <path_to_old_compiler>/opt/intel/composerxe/bin/ifort -c mwe.f90
warning #13003: message verification failed for: 28003; reverting to internal message
mwe.f90(29): warning #6738: The type/rank/keyword signature for this specific procedure matches another specific procedure that shares the same generic-name.   [SCALPROD_EV]
  complex(dp) function scalprod_Ev(E, v)
-----------------------^
[user@host trunk]$ echo $?
0

With the brand new compiler I get:

[user@host trunk]$ ifort --version
ifort (IFORT) 19.1.1.217 20200306
Copyright (C) 1985-2020 Intel Corporation.  All rights reserved.

[user@host trunk]$ ifort -c mwe.f90
mwe.f90(29): error #5286: Ambiguous generic interface SCALPROD: previously declared specific procedure SCALPROD_VE is not distinguishable from this declaration. [SCALPROD_EV]
  complex(dp) function scalprod_Ev(E, v)
-----------------------^
compilation aborted for mwe.f90 (code 1)
[user@host trunk]$ echo $?
1

To be honest - I can imagine (somehow) the interface problem, probably because there is no way to distinguish between two TYPE-arguments, although the content of both TYPEs is different.

But why does the old compiler eat this code and the new compiler not? Is there probably a command line option that might make the code compile using the new compiler?

 

Any advice is appreciated.

 

Thanks,

Michael

0 Kudos
1 Reply
Steve_Lionel
Honored Contributor III
665 Views

It is not at all unusual for compilers to add error checking in later releases. That an older compiler accepted the code doesn't mean the code is valid.

This particular case is one where I lobbied the compiler developers to improve the diagnostic, providing more information. I probably also insisted that it be an error, so if you want to curse me, feel free.

The problem here is that the only difference between the two specific routines is the order of the names. V is always type(ThreeVec) and E is always type(cField). So if one does something like this:

type(ThreeVec) :: TV
type(cField) :: CV
...
x = scalprod (V=TV,E=CV)

which should it use?

You can fix it this way:

  complex(dp) function scalprod_Ev(E2, v2)
    type(ThreeVec), intent(in) :: v2
    type(cField), intent(in) :: E2
    ! ---
    scalprod_Ev = scalprod_vE(v2, E2)
  end function scalprod_Ev

as long as you don't use argument names.

0 Kudos
Reply