[Bug fortran/63797] New: Bogus ambiguous reference to 'sqrt'

burnus at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Sun Nov 9 17:13:00 GMT 2014


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



More information about the Gcc-bugs mailing list