[Bug fortran/105138] [7,8,9,10,11,12,F95] Bogus error when function name does not shadow an intrinsic when RESULT clause is used

kargl at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Sat Apr 2 19:03:18 GMT 2022


https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105138

--- Comment #7 from kargl at gcc dot gnu.org ---
It seems the problem is that gfortran does not know
that a function name is local to its own scoping unit
when a result-name is used.

First, if the function is contained in a module it seems
to work correctly.  Consider,

  module foo
    implicit none
  contains
    recursive function log_gamma(z) result(res)
      complex,intent(in) :: z
      complex  :: res
      complex x
      if (real(z) == 0) then
        res = 42
      else
        x = (0,1)
        res = log_gamma(x)
      end if
    end function log_gamma
  end module foo

  program bar
    use foo
    implicit none
    complex z
    z = log_gamma(cmplx(2.,3.))
    print *, z
  end program bar

% gfcx -Wall -o z a.f90
a.f90:4:3:

    4 |    recursive function log_gamma(z) result(res)
      |   1
Warning: 'log_gamma' declared at (1) may shadow the intrinsic of
the same name.  In order to call the intrinsic, explicit INTRINSIC
declarations may be required. [-Wintrinsic-shadow]
% ./z
             (42.0000000,0.00000000)

Now, consider 

  recursive function log_gamma(z) result(res)
    complex,intent(in) :: z
    complex  :: res
    complex x
    if (real(z) == 0) then
      res = 42
    else
      x = (0,1)
      res = log_gamma(x)
    end if
  end function log_gamma

  program bar
    implicit none
    complex z
    z = log_gamma(cmplx(2.,3.))
    print *, z
  end program bar

% gfcx -Wall -o z a.f90
a.f90:1:0:

    1 | recursive function log_gamma(z) result(res)
      | 
Warning: 'log_gamma' declared at (1) is also the name of an intrinsic.
It can only be called via an explicit interface or if declared EXTERNAL.
[-Wintrinsic-shadow]
a.f90:9:22:

    9 |       res = log_gamma(x)
      |                      1
Error: 'x' argument of 'log_gamma' intrinsic at (1) must be REAL
a.f90:16:17:

   16 |    z = log_gamma(cmplx(2.,3.))
      |                 1
Error: 'x' argument of 'log_gamma' intrinsic at (1) must be REAL


I believe the first error is wrong.  The local function name should
block the intrinsic name.  The second error is correct, because the
recursive function requires an explicit interface in program bar and
gfortran is picking up the intrinsic function.

If the function is modified to

  recursive function log_gamma(z) result(res)
    complex,intent(in) :: z
    complex  :: res
    complex x
    if (real(z) == 0) then
      res = 42
    else
      block
        complex, external :: log_gamma
        x = (0,1)
        res = log_gamma(x)
      end block
    end if
  end function log_gamma

then the first error message does not occur.  The block...end block
should not be required.  The second error message remains as it
should.

If the program is modified to 

  program bar
    implicit none
    complex z
    complex, external :: log_gamma
    z = log_gamma(cmplx(2.,3.))
    print *, z
  end program bar

or 

  program bar
    implicit none
    interface
      recursive function log_gamma(z) result(res)
      complex,intent(in) :: z
      complex  :: res
      end function log_gamma
    end interface
    complex z
    z = log_gamma(cmplx(2.,3.))
    print *, z
  end program bar

it compiles and runs with the block...end block modified function
For completeness, if log_gamma() is a contained routine within the
program it compiles and runs.

  program bar
    implicit none
    complex z
    z = log_gamma(cmplx(2.,3.))
    print *, z
  contains
    recursive function log_gamma(z) result(res)
      complex,intent(in) :: z
      complex  :: res
      complex x
      if (real(z) == 0) then
        res = 42
      else
        x = (0,1)
        res = log_gamma(x)
      end if
    end function log_gamma
  end program bar


% gfcx -Wall -o z a.f90
a.f90:7:4:

    7 |     recursive function log_gamma(z) result(res)
      |    1
Warning: 'log_gamma' declared at (1) may shadow the intrinsic of
the same name.  In order to call the intrinsic, explicit INTRINSIC
declarations may be required. [-Wintrinsic-shadow]
%./z
             (42.0000000,0.00000000)


More information about the Gcc-bugs mailing list