So I have this legacy code that compiles with ifort 13.1.0 with a warning, but which generates an error in ifort 188.8.131.52. 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) 184.108.40.206 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.
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.