https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63797
Bug ID: 63797 Summary: Bogus ambiguous reference to 'sqrt' Product: gcc Version: 5.0 Status: UNCONFIRMED Keywords: rejects-valid Severity: normal Priority: P3 Component: fortran Assignee: unassigned at gcc dot gnu.org Reporter: burnus at gcc dot gnu.org Reported by David Smith on COMP-FORTRAN-90, https://www.jiscmail.ac.uk/cgi-bin/webadmin?A2=comp-fortran-90;75486336.1411 The following code is rejected with: y = sqrt(x) 1 Error: Name 'sqrt' at (1) is an ambiguous reference to 'sqrt' from module '(intrinsic)' Malcolm Cohen writes: ------------------------<cut>-------------------------------- I don't see anything wrong with this. Neither does the NAG compiler." > module mod1 > ! double precision :: max_allowed = 1.0d+75 > double precision :: max_allowed = sqrt(sqrt(huge(max_allowed))) This will result in the intrinsic SQRT being exported from MOD1. This is not a problem in the standard, which indeed allows this, but I guess this is the source of the problem..." > interface sqrt > module procedure sqrt_pair Here is the second SQRT, this is a user-defined generic name." > y = sqrt(x) Here is the line that gfortran complains about. At this point there are indeed two SQRT's visible. But the Fortran standard explicitly allows this: (I'm quoting the draft F2015 here, but similar text exists in every standard since Fortran 90.) "Two or more accessible entities, other than generic interfaces or defined operators, may have the same local identifier only if the identifier is not used. Generic interfaces and defined operators are handled as described in 12.4.3.4." Both the intrinsic SQRT and the user-defined SQRT are generic, so the first sentence does not apply, and the second sentence does. In other words, you are allowed to import the same generic name from different modules, as long as that generic follows the rules in 12.4.3.4 (which lay out requirements on non-ambiguity, both being subroutines or both being functions, etc.). 12.4.3.4 goes on for pages in excruciating detail which I will not reproduce here! So this looks like a simple gfortran bug to me. Doubtless you could work around it by putting a PRIVATE SQRT statement in mod1 (since you probably did not intend to export the intrinsic SQRT from there anyway). ------------------------</cut>-------------------------------- And here's the code: ------------------------<cut>-------------------------------- module mod1 ! double precision :: max_allowed = 1.0d+75 double precision :: max_allowed = sqrt(sqrt(huge(max_allowed))) integer :: kw = 6 end module mod1 module mod2 type pair double precision :: a_pair(2) = (/ 0, 0 /) end type interface sqrt module procedure sqrt_pair end interface contains function sqrt_pair(a) use mod1 implicit none type (pair) :: a, sqrt_pair intent (in) :: a sqrt_pair%a_pair(1) = min( sqrt(a%a_pair(1)), max_allowed ) sqrt_pair%a_pair(2) = min( sqrt(a%a_pair(2)), max_allowed ) end function sqrt_pair end module mod2 program test use mod1 use mod2 type (pair) x, y x%a_pair(1) = 1.23d+100 x%a_pair(2) = 1.23d+200 y = sqrt(x) write (kw,*) ' y = ', y%a_pair(1), y%a_pair(2) end program test