https://gcc.gnu.org/g:2e334900f4ddcd804e3b324402544a572d306ab6

commit r16-1193-g2e334900f4ddcd804e3b324402544a572d306ab6
Author: Robert Dubner <rdub...@symas.com>
Date:   Thu Jun 5 10:53:02 2025 -0400

    cobol: Guard clock_gettime(). [PR119975]
    
    This attempts to eliminate "'clock_gettime' not declared..." when
    building on x86_64-apple-darwin15.6.0.  Calls to clock_gettime have been
    reduced to two locations.  Both have been guarded with
    
    gcc/cobol/ChangeLog:
    
            PR cobol/119975
            * genapi.cc (parser_intrinsic_call_0): Use get_time_nanoseconds().
            * genutil.cc (get_time_64): Rename to get_time_nanoseconds().
            (get_time_nanoseconds): Likewise.
            * genutil.h (get_time_64): Likewise.
            (get_time_nanoseconds): Likewise.
            * util.cc (class cbl_timespec): Timing routine uses
            get_time_nanoseconds().
            (operator-): Likewise.
            (parse_file): Likewise.
    
    libgcobol/ChangeLog:
    
            PR cobol/119975
            * configure.ac: AC_CHECK_LIB(rt, clock_gettime).
            * config.h.in: Likewise.
            * configure: Likewise.
            * gfileio.cc: Remove in-line cppcheck-suppress.
            * intrinsic.cc (timespec_to_string): Use guarded clock_gettime().
            (__gg__current_date): Likewise.
            (__gg__seconds_past_midnight): Likewise.
            (__gg__formatted_current_date): Likewise.
            (__gg__random): Likewise.
            (__gg__random_next): Likewise.
            (__gg__when_compiled): Likewise.
            * libgcobol.cc (cobol_time): Likewise.
            (get_time_nanoseconds): Likewise.
            (__gg__clock_gettime): Likewise.
            (__gg__get_date_hhmmssff): Likewise.
            * libgcobol.h (__gg__clock_gettime): Likewise.
            (struct cbl_timespec): Likewise.

Diff:
---
 gcc/cobol/genapi.cc    |  2 +-
 gcc/cobol/genutil.cc   |  2 +-
 gcc/cobol/genutil.h    |  2 +-
 gcc/cobol/util.cc      | 19 +++++++++++++-----
 libgcobol/config.h.in  |  3 +++
 libgcobol/configure    | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++
 libgcobol/configure.ac | 11 +++++++++++
 libgcobol/gfileio.cc   |  2 --
 libgcobol/intrinsic.cc | 14 ++++++-------
 libgcobol/libgcobol.cc | 34 ++++++++++++++++++++++++++++----
 libgcobol/libgcobol.h  | 10 +++++++++-
 11 files changed, 130 insertions(+), 22 deletions(-)

diff --git a/gcc/cobol/genapi.cc b/gcc/cobol/genapi.cc
index 5e983ab503c2..bde8151ece79 100644
--- a/gcc/cobol/genapi.cc
+++ b/gcc/cobol/genapi.cc
@@ -10491,7 +10491,7 @@ parser_intrinsic_call_0(cbl_field_t *tgt,
     {
     // Pass __gg__when_compiled() the time from right now.
     struct timespec tp;
-    uint64_t now = get_time_64();
+    uint64_t now = get_time_nanoseconds();
     tp.tv_sec  = now / 1000000000;
     tp.tv_nsec = now % 1000000000;
 
diff --git a/gcc/cobol/genutil.cc b/gcc/cobol/genutil.cc
index e971043164c7..f1098f02768e 100644
--- a/gcc/cobol/genutil.cc
+++ b/gcc/cobol/genutil.cc
@@ -2121,7 +2121,7 @@ qualified_data_location(cbl_refer_t &refer)
   }
 
 uint64_t
-get_time_64()
+get_time_nanoseconds()
 {
   // This code was unabashedly stolen from gcc/timevar.cc.
   // It returns the Unix epoch with nine decimal places.
diff --git a/gcc/cobol/genutil.h b/gcc/cobol/genutil.h
index 43102d7cc544..fb582e5a493f 100644
--- a/gcc/cobol/genutil.h
+++ b/gcc/cobol/genutil.h
@@ -155,7 +155,7 @@ void      build_array_of_fourplets( int ngroup,
                                     size_t N,
                                     cbl_refer_t *refers);
 void      get_depending_on_value_from_odo(tree retval, cbl_field_t *odo);
-uint64_t  get_time_64();
+uint64_t  get_time_nanoseconds();
 
 
 #endif
diff --git a/gcc/cobol/util.cc b/gcc/cobol/util.cc
index 75a0b26c0a91..e92f069bee1b 100644
--- a/gcc/cobol/util.cc
+++ b/gcc/cobol/util.cc
@@ -65,6 +65,7 @@
 #include "inspect.h"
 #include "../../libgcobol/io.h"
 #include "genapi.h"
+#include "genutil.h"
 
 #pragma GCC diagnostic ignored "-Wunused-result"
 #pragma GCC diagnostic ignored "-Wmissing-field-initializers"
@@ -2141,22 +2142,25 @@ cobol_fileline_set( const char line[] ) {
   return file.name;
 }
 
+//#define TIMING_PARSE
+#ifdef TIMING_PARSE
 class cbl_timespec {
-  struct timespec now;
+  uint64_t now; // Nanoseconds
  public:
   cbl_timespec() {
-    clock_gettime(CLOCK_MONOTONIC, &now);
+    now = get_time_nanoseconds();
   }
   double ns() const {
-    return now.tv_sec * 1000000000 + now.tv_nsec;
+    return now;
   }
   friend double operator-( const cbl_timespec& now, const cbl_timespec& then );
 };
 
 double
-operator-( const cbl_timespec& then, const cbl_timespec& now ) {
+operator-( const cbl_timespec& now, const cbl_timespec& then ) {
   return (now.ns() - then.ns()) / 1000000000;
 }
+#endif
 
 static int
 parse_file( const char filename[] )
@@ -2172,15 +2176,20 @@ parse_file( const char filename[] )
     return 0;
   }
 
+#ifdef TIMING_PARSE
   cbl_timespec start;
+#endif
 
   int erc = yyparse();
 
+#ifdef TIMING_PARSE
   cbl_timespec finish;
   double dt  = finish - start;
+  printf("Overall parse & generate time is %.6f seconds\n", dt);
+#endif
+
   parser_leave_file();
 
-  //printf("Overall parse & generate time is %.6f seconds\n", dt);
 
   fclose (yyin);
 
diff --git a/libgcobol/config.h.in b/libgcobol/config.h.in
index ee3dd6b21514..1b511d0330d5 100644
--- a/libgcobol/config.h.in
+++ b/libgcobol/config.h.in
@@ -3,6 +3,9 @@
 /* Define to 1 if the target assembler supports thread-local storage. */
 #undef HAVE_CC_TLS
 
+/* Define to 1 if you have the `clock_gettime' function. */
+#undef HAVE_CLOCK_GETTIME
+
 /* Define to 1 if you have the <complex.h> header file. */
 #undef HAVE_COMPLEX_H
 
diff --git a/libgcobol/configure b/libgcobol/configure
index 5f319eedf538..72715177c230 100755
--- a/libgcobol/configure
+++ b/libgcobol/configure
@@ -17275,6 +17275,59 @@ if test "$ac_res" != no; then :
 fi
 
 
+# Copied from gcc/configure.ac. 2025-06-05 R.J.Dubner
+# At least for glibc, clock_gettime is in librt.  But don't pull that
+# in if it still doesn't give us the function we want.
+ac_cv_func_clock_gettime=no
+if test $ac_cv_func_clock_gettime = no; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for clock_gettime in -lrt" 
>&5
+$as_echo_n "checking for clock_gettime in -lrt... " >&6; }
+if ${ac_cv_lib_rt_clock_gettime+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lrt  $LIBS"
+if test x$gcc_no_link = xyes; then
+  as_fn_error $? "Link tests are not allowed after GCC_NO_EXECUTABLES." 
"$LINENO" 5
+fi
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char clock_gettime ();
+int
+main ()
+{
+return clock_gettime ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+  ac_cv_lib_rt_clock_gettime=yes
+else
+  ac_cv_lib_rt_clock_gettime=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_rt_clock_gettime" 
>&5
+$as_echo "$ac_cv_lib_rt_clock_gettime" >&6; }
+if test "x$ac_cv_lib_rt_clock_gettime" = xyes; then :
+  LIBS="-lrt $LIBS"
+
+$as_echo "#define HAVE_CLOCK_GETTIME 1" >>confdefs.h
+
+fi
+
+fi
+
 have_iec_60559_libc_support=no
 if test "x$ac_cv_func_strtof128$ac_cv_func_strfromf128" = xyesyes \
    && test "x$libgcobol_have_sinf128$libgcobol_have_cacosf128" = xyesyes; then
diff --git a/libgcobol/configure.ac b/libgcobol/configure.ac
index 13326960515a..acfca7e68e43 100644
--- a/libgcobol/configure.ac
+++ b/libgcobol/configure.ac
@@ -232,6 +232,17 @@ AC_SEARCH_LIBS([sinf128], [c m], 
libgcobol_have_sinf128=yes)
 libgcobol_have_cacosf128=no
 AC_SEARCH_LIBS([cacosf128], [c m], libgcobol_have_cacosf128=yes)
 
+# Copied from gcc/configure.ac. 2025-06-05 R.J.Dubner
+# At least for glibc, clock_gettime is in librt.  But don't pull that
+# in if it still doesn't give us the function we want.
+ac_cv_func_clock_gettime=no
+if test $ac_cv_func_clock_gettime = no; then
+  AC_CHECK_LIB(rt, clock_gettime,
+    [LIBS="-lrt $LIBS"
+     AC_DEFINE(HAVE_CLOCK_GETTIME, 1,
+              [Define to 1 if you have the `clock_gettime' function.])])
+fi
+
 have_iec_60559_libc_support=no
 if test "x$ac_cv_func_strtof128$ac_cv_func_strfromf128" = xyesyes \
    && test "x$libgcobol_have_sinf128$libgcobol_have_cacosf128" = xyesyes; then
diff --git a/libgcobol/gfileio.cc b/libgcobol/gfileio.cc
index c09102168e46..912428880620 100644
--- a/libgcobol/gfileio.cc
+++ b/libgcobol/gfileio.cc
@@ -28,8 +28,6 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-// cppcheck-suppress-file postfixOperator
-
 #include <err.h>
 #include <fcntl.h>
 #include <unistd.h>
diff --git a/libgcobol/intrinsic.cc b/libgcobol/intrinsic.cc
index 1053bf627435..2d8d79c1c7c7 100644
--- a/libgcobol/intrinsic.cc
+++ b/libgcobol/intrinsic.cc
@@ -167,7 +167,7 @@ JD_to_DOW(double JD)
 
 static
 char *
-timespec_to_string(char *retval, struct timespec &tp)
+timespec_to_string(char *retval, struct cbl_timespec &tp)
   {
   /*
   Returns a 21-character string:
@@ -1218,7 +1218,7 @@ void
 __gg__current_date(cblc_field_t *dest)
   {
   // FUNCTION CURRENT-DATE
-  struct timespec tp = {};
+  struct cbl_timespec tp = {};
   __gg__clock_gettime(CLOCK_REALTIME, &tp); // time_t tv_sec; long tv_nsec
 
   char retval[DATE_STRING_BUFFER_SIZE];
@@ -1232,7 +1232,7 @@ void
 __gg__seconds_past_midnight(cblc_field_t *dest)
   {
   // SECONDS-PAST-MIDNIGHT
-  struct timespec tp = {};
+  struct cbl_timespec tp = {};
   struct tm tm;
   __int128 retval=0;
   
@@ -1484,7 +1484,7 @@ __gg__formatted_current_date( cblc_field_t *dest, // 
Destination string
       }
     }
 
-  struct timespec ts = {};
+  struct cbl_timespec ts = {};
   __gg__clock_gettime(CLOCK_REALTIME, &ts);
 
   struct tm tm = {};
@@ -3432,7 +3432,7 @@ __gg__random( cblc_field_t *dest,
     buf->state = NULL;
     state = (char *)malloc(state_len);
 
-    struct timespec ts;
+    struct cbl_timespec ts;
     __gg__clock_gettime(CLOCK_REALTIME, &ts);
     initstate_r( ts.tv_nsec, state, state_len, buf);
     }
@@ -3472,7 +3472,7 @@ __gg__random_next(cblc_field_t *dest)
     buf = (random_data *)malloc(sizeof(struct random_data));
     buf->state = NULL;
     state = (char *)malloc(state_len);
-    struct timespec ts;
+    struct cbl_timespec ts;
     __gg__clock_gettime(CLOCK_REALTIME, &ts);
     initstate_r( ts.tv_nsec, state, state_len, buf);
     }
@@ -3776,7 +3776,7 @@ extern "C"
 void
 __gg__when_compiled(cblc_field_t *dest, size_t tv_sec, long tv_nsec)
   {
-  struct timespec tp = {};
+  struct cbl_timespec tp = {};
   tp.tv_sec  = tv_sec;
   tp.tv_nsec = tv_nsec;
   char retval[DATE_STRING_BUFFER_SIZE];
diff --git a/libgcobol/libgcobol.cc b/libgcobol/libgcobol.cc
index f17c659bdd50..e89ca0a02381 100644
--- a/libgcobol/libgcobol.cc
+++ b/libgcobol/libgcobol.cc
@@ -2289,7 +2289,7 @@ get_binary_value_local(  int                 *rdigits,
 static time_t
 cobol_time()
   {
-  struct timespec tp;
+  struct cbl_timespec tp;
   __gg__clock_gettime(CLOCK_REALTIME, &tp);
   return tp.tv_sec;
   }
@@ -2402,10 +2402,32 @@ int_from_digits(const char * &p, int ndigits)
   return retval;
   }
 
+uint64_t
+get_time_nanoseconds()
+{
+  // This code was unabashedly stolen from gcc/timevar.cc.
+  // It returns the Unix epoch with nine decimal places.
+
+  uint64_t retval = 0;
+
+#ifdef HAVE_CLOCK_GETTIME
+  struct timespec ts;
+  clock_gettime (CLOCK_REALTIME, &ts);
+  retval = ts.tv_sec * 1000000000 + ts.tv_nsec;
+  return retval;
+#endif
+#ifdef HAVE_GETTIMEOFDAY
+  struct timeval tv;
+  gettimeofday (&tv, NULL);
+  retval = tv.tv_sec * 1000000000 + tv.tv_usec * 1000;
+  return retval;
+#endif
+  return retval;
+}
 
 extern "C"
 void
-__gg__clock_gettime(clockid_t clk_id, struct timespec *tp)
+__gg__clock_gettime(clockid_t clk_id, struct cbl_timespec *tp)
   {
   const char *p = getenv("GCOBOL_CURRENT_DATE");
 
@@ -2435,7 +2457,11 @@ __gg__clock_gettime(clockid_t clk_id, struct timespec 
*tp)
     }
   else
     {
-    clock_gettime(clk_id, tp);
+    timespec tm;
+    clock_gettime(clk_id, &tm);
+    uint64_t ns = get_time_nanoseconds();
+    tp->tv_sec  = ns/1000000000;
+    tp->tv_nsec = ns%1000000000;
     }
   }
 
@@ -2445,7 +2471,7 @@ __gg__get_date_hhmmssff()
   {
   char ach[32];
 
-  struct timespec tv;
+  struct cbl_timespec tv;
   __gg__clock_gettime(CLOCK_REALTIME, &tv);
 
   struct tm tm;
diff --git a/libgcobol/libgcobol.h b/libgcobol/libgcobol.h
index ace321d20e41..4aa2cffb8035 100644
--- a/libgcobol/libgcobol.h
+++ b/libgcobol/libgcobol.h
@@ -104,7 +104,15 @@ extern "C" char __gg__get_decimal_separator();
 extern "C" char __gg__get_decimal_point();
 extern "C" char * __gg__get_default_currency_string();
 
-extern "C" void __gg__clock_gettime(clockid_t clk_id, struct timespec *tp);
+struct cbl_timespec
+  {
+  /*  You keep using that word "portability".  I do not think it means what
+      you think it means. */
+  time_t  tv_sec;    // Seconds.
+  long    tv_nsec;   // Nanoseconds.
+  } ;
+
+extern "C" void __gg__clock_gettime(clockid_t clk_id, struct cbl_timespec *tp);
 
 extern "C" GCOB_FP128 __gg__float128_from_location(
                                         const cblc_field_t *var,

Reply via email to