This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug fortran/33162] INTRINSIC functions as ACTUAL argument
- From: "burnus at gcc dot gnu dot org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 21 Oct 2007 09:30:28 -0000
- Subject: [Bug fortran/33162] INTRINSIC functions as ACTUAL argument
- References: <bug-33162-13404@http.gcc.gnu.org/bugzilla/>
- Reply-to: gcc-bugzilla at gcc dot gnu dot org
------- Comment #4 from burnus at gcc dot gnu dot org 2007-10-21 09:30 -------
Several intrinsic functions come as specific and as generic functions. For
instance
COS as generic function takes as argument REAL(k) and COMPLEX(k), k=4,8,10,16
and returns the same type and kind as it got as argument.
whereas
COS as specific function takes as argument REAL(4) and returns REAL(4)
DCOS as specific function takes as argument REAL(8) and returns REAL(8)
Therefore,
intrinsic cos
COS(1.0) ! generic intrinsic function; matches specific function COS
COS(1d0) ! generic intrinsic function; matches specific function DCOS
end
are valid, however,
intrinsic dcos
DCOS(1.0)
is wrong as the specific function requires REAL(8) as argument and not REAL(4).
NAG f95:
ERROR: Wrong data type for argument X to the DCOS intrinsic
g95:
Error: Type of argument 'x' in call to 'dcos' at (1) should be REAL(8),
not REAL(4)
In order to detect this, either check.c has to be refined or for specific
function the interface has to be stored. The latter is needed in the following.
If one passes an intrinsic function as actual argument, e.g.
call sub(cos) ! see valid program in comment 1
the procedure is the specific intrinsic and not the generic intrinsic; in this
case this it means that "cos" gets REAL(4) as argument and returns REAL(4).
Currently, this information is not stored in intrinsic.c. If it were, one could
simply do:
module mm
contains
subroutine foo(trig)
intrinsic cos
procedure(cos) :: trig ! real(4) function
print *, trig(1.0)
end subroutine
end module mm
!and then
use mm
call foo(sin) ! specific function with real(4)
call foo(tan) ! specific function with real(4)
call foo(dcos)! wrong: specific function with real(8)
end
The statement
PROCEDURE(cos) :: trig
declares trig as a procedure which has the same interface as the specific
function cos. In this case the interface of the specific COS is probably:
elemental function cos(x)
real(4), intent(in) :: x
real(4) :: cos
end function cos
Thus, in order to implement
"PROCEDURE( intrinsic specific function )"
one needs to know (in match_procedure) the explicit interface of that function.
While the PROCEDURE statement is a Fortran 2003 feature, the program in comment
1 is a valid Fortran 95 program. The problem of the patch in comment 2 is that
it also allows the following program which is invalid:
module m
implicit none
contains
subroutine sub(a)
interface
function a()
real :: a
end function a
end interface
print *, a()
end subroutine sub
end module m
use m
implicit none
intrinsic cos
! NAG f95:
! Error: Specific intrinsic COS has more arguments than dummy proc A
call sub(cos)
end
Note that the program in comment 4 is wrong since
use m
imports the interface of my1 and and my2, while the following declares the
interfaces again:
procedure(dcos):: my1
procedure(cos) :: my2
The reason that Janus has not implemented "PROCEDURE( specific intrinsic )" is
that we currently do not store the interface of specific intrinsics, which made
the support a bit difficult.
(PROCEDURE(otherProcedure) is already supported for non-intrinsic procedures
such as:
procedure(foo) :: bar
call bar(4,4.4)
contains
subroutine foo(x,y)
integer :: x
real :: y
end subroutine
end ! )
--
burnus at gcc dot gnu dot org changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |burnus at gcc dot gnu dot
| |org
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33162