Even though this MRE ran on four platforms, before reporting
this as a bug is it standard Fortran to alias an intrinsic
this way? I am starting to have doubts now.
program mre
implicit none
procedure(acos), pointer :: p
p => acos
print *, p(1.)
end mre
Compiler Explorer comparison ...
OUPUT OUTPUT
COMPILER LINE
+aoccflang520 : 2 0.000000
+flangtrunk : 2 0.
+nvfortran_x86_26_3 : 2 0.000000
+ifxlatest : 2 0.0000000E+00
!ifxlatest : 4 /app/example.f90(1): warning #8190: Argument checking is not yet supported for procedures declared with an intrinsic procedure as interface. [ACOS]
!ifxlatest : 5 procedure(acos), pointer :: p
!ifxlatest : 6 ----------^
!ifxlatest : 7 /app/example.f90(1): warning #8190: Argument checking is not yet supported for procedures declared with an intrinsic procedure as interface. [ACOS]
!ifxlatest : 8 procedure(acos), pointer :: p
!ifxlatest : 9 ----------^
-lfortranlatest : 3 Program terminated with signal: SIGSEGV
-gfortran161 : 4 1 | procedure(acos), pointer :: p
-gfortran161 : 5 | 1~
-gfortran161 : 6 Error: Procedure pointer 'p' at (1) shall not be elemental
program mre
use iso_fortran_env, only : real64
implicit none
abstract interface
function unary_real64(x) result(y)
import :: real64
real(real64), intent(in) :: x
real(real64) :: y
end function unary_real64
end interface
intrinsic :: dacos
procedure(unary_real64), pointer :: p
p => dacos
print *, p(1.0_real64)
end program mre
In your example’s case, I think it’s okay, since the compiler should interpret acos as a specific intrinsic procedure (that happens to coincide with the generic name), and that specific intrinsic is in the list of unrestricted ones (Table 16.2).
The applicable constraint for procedure-declaration-stmt is
C1519 (R1518) The procedure-name shall be the name of a nonelemental external or module procedure, or a specific intrinsic function listed in Table 16.2.
The only problem is that any usage of specific names for intrinsic procedures is obsolescent.
So maybe gfortran and/or lfortran have a specific (no pun intended) flag for said usage?
Thanks to everyone! In this particular case it ended up being easier to call the intrinsic from a wrapper script that just handles real64 for unrelated reasons but I will hold off on a bug report unless the abstract type fails as well and then mention it in passing. This was encountered in third-party code so I will discuss this with them if they want to improve portability. I have aliased intrinsics but not for this reason I have put the intrinsics in modules so I can rename them by use association but I can see needing to do this in the future.
I think this is the typical solution to this problem, especially involving generic intrinsics. If you do this with an internal procedure, then the compiler can see the entire procedure and has the opportunity to optimize the pointer reference all the way down to the specific intrinsic. Also, the internal procedure (i.e. with contains) means that the global namespace is unaffected.