autoconf: Fortran Cray pointer macro support

https://github.com/libsdl-org/autoconf/commit/6cfdc564894709122e71700ee95a71a4cb992a60

From 6cfdc564894709122e71700ee95a71a4cb992a60 Mon Sep 17 00:00:00 2001
From: Marshall Ward <[EMAIL REDACTED]>
Date: Wed, 11 Aug 2021 20:43:36 -0400
Subject: [PATCH] Fortran Cray pointer macro support

This patch adds the AC_F77_CRAY_POINTERS and AC_FC_CRAY_POINTERS macros,
which test if the Fortran compiler supports Cray pointers.

The macros are written such that the tests share a common backend
(_AC_FC_CRAY_POINTERS) which works on both F77 and FC compilers.
Wrappers are provided to address any future potential compatibility
issues.

The macros include additional tests for particular flags required by
GFortran and PGI compilers.  The current set of flags is sparse, but can
be extended for other compilers if needed.

Documentation and a minimal test of the macro have been included.

Two minor variable name typos (@EXEEXT@ as @EEXEXT@) were also fixed in
two of the other Fortran tests.
---
 doc/autoconf.texi       | 22 ++++++++++
 lib/autoconf/fortran.m4 | 70 ++++++++++++++++++++++++++++++++
 tests/fortran.at        | 89 ++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 179 insertions(+), 2 deletions(-)

diff --git a/doc/autoconf.texi b/doc/autoconf.texi
index 9f632ced..590be1c4 100644
--- a/doc/autoconf.texi
+++ b/doc/autoconf.texi
@@ -8741,6 +8741,28 @@ The substituted value of @code{FC_MODOUT} may refer to the
 the significant trailing whitespace in a @file{Makefile}.
 @end defmac
 
+@defmac AC_F77_CRAY_POINTERS (@ovar{action-if-success}, @
+  @dvar{action-if-failure, AC_MSG_FAILURE})
+@defmacx AC_FC_CRAY_POINTERS (@ovar{action-if-success}, @
+  @dvar{action-if-failure, AC_MSG_FAILURE})
+@acindex{F77_CRAY_POINTERS}
+@acindex{FC_CRAY_POINTERS}
+@caindex fc_cray_pointer
+
+Try to ensure that the Fortran compiler (@code{$F77} or @code{$FC})
+accepts Cray pointers.  If successful, the @var{action-if-success} is
+called and any needed flags are added to @code{FFLAGS} or
+@code{FCFLAGS}.  Otherwise, @var{action-if-failure} is called, which
+defaults to failing with an error message.
+
+Cray pointers are a non-standard extension supported by many Fortran
+compilers which allow an integer to be declared as C-like pointer to
+a target variable.
+
+The result of this test, or @samp{none} or @samp{unknown}, is cached in
+the @code{ac_cv_f77_cray_ptr} or @code{ac_cv_fc_cray_ptr} variable.
+@end defmac
+
 
 @node Go Compiler
 @subsection Go Compiler Characteristics
diff --git a/lib/autoconf/fortran.m4 b/lib/autoconf/fortran.m4
index dd9d4bd4..d393c669 100644
--- a/lib/autoconf/fortran.m4
+++ b/lib/autoconf/fortran.m4
@@ -1861,3 +1861,73 @@ AC_CONFIG_COMMANDS_PRE([case $FC_MODOUT in #(
   *\ ) FC_MODOUT=$FC_MODOUT'${ac_empty}' ;;
 esac])dnl
 ])
+
+
+# _AC_FC_CRAY_POINTERS([ACTION-IF-SUCCESS], [ACTION-IF-FAILURE = FAILURE])
+#-------------------------------------------------------------------------
+# Try to ensure that the Fortran compiler supports Cray pointers, a
+# non-standard extension that provides a C-like pointer in Fortran.
+#
+# If successful, ACTION-IF-SUCCESS is called.  If no argument is provided, then
+# any necessary flags are added to F[C]FLAGS.  Otherwise, ACTION-IF-FAILURE is
+# called, which defaults to failing with an error message.
+#
+# Most compilers provide an implementation of Cray pointers, and often no
+# additional flags are required to enable support.  A partial list of compilers
+# and flags which may be required are listed below.
+#
+# The known flags are:
+#   -fcray-pointer: gfortran
+#   -Mcray-pointer: PGI
+AC_DEFUN([_AC_FC_CRAY_POINTERS], [
+  AC_MSG_CHECKING([for $[]_AC_FC[] option to support Cray pointers])
+  AC_CACHE_VAL([ac_cv_[]_AC_LANG_ABBREV[]_cray_ptr], [
+    ac_cv_[]_AC_LANG_ABBREV[]_cray_ptr='unknown'
+    ac_save_[]_AC_LANG_PREFIX[]FLAGS=$[]_AC_LANG_PREFIX[]FLAGS
+    for ac_option in none -fcray-pointer -Mcray=pointer; do
+      test "$ac_option" != none && _AC_LANG_PREFIX[]FLAGS="$ac_save_[]_AC_LANG_PREFIX[]FLAGS $ac_option"
+      AC_COMPILE_IFELSE(
+        [AC_LANG_PROGRAM([], [
+      integer aptr(2)
+      pointer (iptr, aptr)
+        ])],
+        [ac_cv_[]_AC_LANG_ABBREV[]_cray_ptr=$ac_option],
+      )
+      _AC_LANG_PREFIX[]FLAGS=$ac_save_[]_AC_LANG_PREFIX[]FLAGS
+      AS_IF([test "$ac_cv_[]_AC_LANG_ABBREV[]_cray_ptr" != unknown], [break])
+    done
+  ])
+  AS_CASE([ac_cv_[]_AC_LANG_ABBREV[]_cray_ptr],
+    [none], [AC_MSG_RESULT([none_needed])],
+    [unknown], [AC_MSG_RESULT([unsupported])],
+    [AC_MSG_RESULT([$ac_cv_[]_AC_LANG_ABBREV[]_cray_ptr])]
+  )
+  AS_IF([test "$ac_cv_[]_AC_LANG_ABBREV[]_cray_ptr" != unknown], [
+    m4_default([$1], [
+      AS_IF([test "$ac_cv_[]_AC_LANG_ABBREV[]_cray_ptr" != none],
+        [_AC_LANG_PREFIX[]FLAGS="$[]_AC_LANG_PREFIX[]FLAGS $ac_cv_[]_AC_LANG_ABBREV[]_cray_ptr"]
+      )
+    ])],
+    [m4_default([$2], [AC_MSG_ERROR(["$[]_AC_FC[] does not support Cray pointers"])])]
+  )
+])
+
+
+# AC_F77_CRAY_POINTERS
+#---------------------
+AC_DEFUN([AC_F77_CRAY_POINTERS], [
+  AC_REQUIRE([AC_PROG_F77])
+  AC_LANG_PUSH([Fortran 77])
+  _AC_FC_CRAY_POINTERS($@)
+  AC_LANG_POP([Fortran 77])
+])
+
+
+# AC_FC_CRAY_POINTERS
+#--------------------
+AC_DEFUN([AC_FC_CRAY_POINTERS], [
+  AC_REQUIRE([AC_PROG_FC])
+  AC_LANG_PUSH([Fortran])
+  _AC_FC_CRAY_POINTERS($@)
+  AC_LANG_POP([Fortran])
+])
diff --git a/tests/fortran.at b/tests/fortran.at
index 907cf6a3..47d01434 100644
--- a/tests/fortran.at
+++ b/tests/fortran.at
@@ -1009,7 +1009,7 @@ AT_DATA([Makefile.in],
 	@FC@ @FCFLAGS@ -c @FCFLAGS_f@ $<
 
 clean:
-	rm -f *.@OBJEXT@ prog@EEXEXT@
+	rm -f *.@OBJEXT@ prog@EXEEXT@
 ]])
 
 # When preceded by 7 spaces and followed by newline, line_80 generates
@@ -1081,7 +1081,7 @@ AT_DATA([Makefile.in],
 	@FC@ @FCFLAGS@ -c @FCFLAGS_f@ $<
 
 clean:
-	rm -f *.@OBJEXT@ prog@EEXEXT@
+	rm -f *.@OBJEXT@ prog@EXEEXT@
 ]])
 
 cat >configure.ac <<EOF
@@ -1192,3 +1192,88 @@ AT_CHECK([./prog], [], [ignore], [ignore])
 AT_CHECK_MAKE([clean])
 
 AT_CLEANUP
+
+
+## --------------------- ##
+## AC_F77_CRAY_POINTERS. ##
+## --------------------- ##
+
+AT_SETUP([AC_F77_CRAY_POINTERS])
+
+AT_DATA([configure.ac],
+[[AC_INIT
+AC_PROG_F77
+AC_F77_CRAY_POINTERS
+AC_CONFIG_FILES([Makefile])
+AC_OUTPUT
+]])
+
+AT_DATA([Makefile.in],
+[[prog@EXEEXT@: prog.@OBJEXT@
+	@F77@ @FFLAGS@ -o $@ prog.@OBJEXT@ @LIBS@
+
+.SUFFIXES: .f .@OBJEXT@
+.f.@OBJEXT@:
+	@F77@ @FFLAGS@ -c $<
+
+clean:
+	rm -f *.@OBJEXT@ prog@EXEEXT@
+]])
+
+AT_DATA([prog.f],
+[[      program main
+      integer aptr(2)
+      pointer (iptr, aptr)
+      end
+]])
+
+AT_CHECK_AUTOCONF
+AT_CHECK_CONFIGURE
+AT_CHECK_MAKE
+AT_CHECK([./prog])
+AT_CHECK_MAKE([clean])
+
+AT_CLEANUP
+
+
+## -------------------- ##
+## AC_FC_CRAY_POINTERS. ##
+## -------------------- ##
+
+AT_SETUP([AC_FC_CRAY_POINTERS])
+
+AT_DATA([configure.ac],
+[[AC_INIT
+AC_PROG_FC
+AC_FC_SRCEXT([f])
+AC_FC_CRAY_POINTERS
+AC_CONFIG_FILES([Makefile])
+AC_OUTPUT
+]])
+
+AT_DATA([Makefile.in],
+[[prog@EXEEXT@: prog.@OBJEXT@
+	@FC@ @FCFLAGS@ -o $@ prog.@OBJEXT@ @LIBS@
+
+.SUFFIXES: .f .@OBJEXT@
+.f.@OBJEXT@:
+	@FC@ @FCFLAGS@ -c @FCFLAGS_f@ $<
+
+clean:
+	rm -f *.@OBJEXT@ prog@EXEEXT@
+]])
+
+AT_DATA([prog.f],
+[[      program main
+      integer aptr(2)
+      pointer (iptr, aptr)
+      end
+]])
+
+AT_CHECK_AUTOCONF
+AT_CHECK_CONFIGURE
+AT_CHECK_MAKE
+AT_CHECK([./prog])
+AT_CHECK_MAKE([clean])
+
+AT_CLEANUP