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,