Taking your word on testing, LGTM
> -----Original Message----- > From: Iain Sandoe <iains....@gmail.com> > Sent: Sunday, March 23, 2025 20:59 > To: jklow...@schemamania.org; rdub...@symas.com; gcc-patches@gcc.gnu.org > Subject: [PATCH] libgcobol: Only use random_r if it is available > [PR119295] > > Tested on x86_64 and aarch64 Linux and x86_64 darwin, > OK for trunk? > thanks > Iain > > This applies on top of > https://gcc.gnu.org/pipermail/gcc-patches/2025-March/678927.html > > --- 8< --- > > We do not have a replacement at the moment, so fall back to using > regular random and friends. > > PR cobol/119295 > > libgcobol/ChangeLog: > > * config.h.in: Regenerate. > * configure: Regenerate. > * configure.ac: Configure random_r and friends > * intrinsic.cc (__gg__random): Use random_r when available. > (__gg__random_next): Likewise. > > Signed-off-by: Iain Sandoe <i...@sandoe.co.uk> > --- > libgcobol/config.h.in | 12 +++++ > libgcobol/configure | 105 ++++++++++++++++++++++++++++++++++++++++- > libgcobol/configure.ac | 3 ++ > libgcobol/intrinsic.cc | 25 ++++++++-- > 4 files changed, 138 insertions(+), 7 deletions(-) > > diff --git a/libgcobol/config.h.in b/libgcobol/config.h.in > index 14ebaeb2b26..e7e1492b579 100644 > --- a/libgcobol/config.h.in > +++ b/libgcobol/config.h.in > @@ -9,6 +9,9 @@ > /* Define if you have the iconv() function and it works. */ > #undef HAVE_ICONV > > +/* Define to 1 if you have the `initstate_r' function. */ > +#undef HAVE_INITSTATE_R > + > /* Define to 1 if you have the <inttypes.h> header file. */ > #undef HAVE_INTTYPES_H > > @@ -18,6 +21,15 @@ > /* Define to 1 if you have the <memory.h> header file. */ > #undef HAVE_MEMORY_H > > +/* Define to 1 if you have the `random_r' function. */ > +#undef HAVE_RANDOM_R > + > +/* Define to 1 if you have the `setstate_r' function. */ > +#undef HAVE_SETSTATE_R > + > +/* Define to 1 if you have the `srandom_r' function. */ > +#undef HAVE_SRANDOM_R > + > /* Define to 1 if you have the <stdint.h> header file. */ > #undef HAVE_STDINT_H > > diff --git a/libgcobol/configure b/libgcobol/configure > index ffbfebd96bf..0a6bafe265b 100755 > --- a/libgcobol/configure > +++ b/libgcobol/configure > @@ -629,6 +629,7 @@ ac_includes_default="\ > # include <unistd.h> > #endif" > > +ac_func_list= > ac_unique_file="Makefile.am" > ac_subst_vars='am__EXEEXT_FALSE > am__EXEEXT_TRUE > @@ -2337,6 +2338,76 @@ rm -f conftest.val > as_fn_set_status $ac_retval > > } # ac_fn_cxx_compute_int > + > +# ac_fn_cxx_check_func LINENO FUNC VAR > +# ------------------------------------ > +# Tests whether FUNC exists, setting the cache variable VAR accordingly > +ac_fn_cxx_check_func () > +{ > + as_lineno=${as_lineno-"$1"} > as_lineno_stack=as_lineno_stack=$as_lineno_stack > + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 > +$as_echo_n "checking for $2... " >&6; } > +if eval \${$3+:} false; then : > + $as_echo_n "(cached) " >&6 > +else > + 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. */ > +/* Define $2 to an innocuous variant, in case <limits.h> declares $2. > + For example, HP-UX 11i <limits.h> declares gettimeofday. */ > +#define $2 innocuous_$2 > + > +/* System header to define __stub macros and hopefully few prototypes, > + which can conflict with char $2 (); below. > + Prefer <limits.h> to <assert.h> if __STDC__ is defined, since > + <limits.h> exists even on freestanding compilers. */ > + > +#ifdef __STDC__ > +# include <limits.h> > +#else > +# include <assert.h> > +#endif > + > +#undef $2 > + > +/* 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 $2 (); > +/* The GNU C library defines this for functions which it implements > + to always fail with ENOSYS. Some functions are actually named > + something starting with __ and the normal name is an alias. */ > +#if defined __stub_$2 || defined __stub___$2 > +choke me > +#endif > + > +int > +main () > +{ > +return $2 (); > + ; > + return 0; > +} > +_ACEOF > +if ac_fn_cxx_try_link "$LINENO"; then : > + eval "$3=yes" > +else > + eval "$3=no" > +fi > +rm -f core conftest.err conftest.$ac_objext \ > + conftest$ac_exeext conftest.$ac_ext > +fi > +eval ac_res=\$$3 > + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 > +$as_echo "$ac_res" >&6; } > + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno > + > +} # ac_fn_cxx_check_func > cat >config.log <<_ACEOF > This file contains any messages produced by compilers while > running configure, to aid debugging if configure makes a mistake. > @@ -2621,6 +2692,10 @@ $as_echo "$as_me: creating cache $cache_file" >&6;} > >$cache_file > fi > > +as_fn_append ac_func_list " random_r" > +as_fn_append ac_func_list " srandom_r" > +as_fn_append ac_func_list " initstate_r" > +as_fn_append ac_func_list " setstate_r" > # Check that the precious variables saved in the cache have kept the same > # value. > ac_cache_corrupted=false > @@ -11546,7 +11621,7 @@ else > lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 > lt_status=$lt_dlunknown > cat > conftest.$ac_ext <<_LT_EOF > -#line 11549 "configure" > +#line 11624 "configure" > #include "confdefs.h" > > #if HAVE_DLFCN_H > @@ -11652,7 +11727,7 @@ else > lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 > lt_status=$lt_dlunknown > cat > conftest.$ac_ext <<_LT_EOF > -#line 11655 "configure" > +#line 11730 "configure" > #include "confdefs.h" > > #if HAVE_DLFCN_H > @@ -17598,6 +17673,32 @@ case $host in > esac > > > +# These are GLIBC > + > + > + > + for ac_func in $ac_func_list > +do : > + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` > +ac_fn_cxx_check_func "$LINENO" "$ac_func" "$as_ac_var" > +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : > + cat >>confdefs.h <<_ACEOF > +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 > +_ACEOF > + > +fi > +done > + > + > + > + > + > + > + > + > + > + > + > if test "${multilib}" = "yes"; then > multilib_arg="--enable-multilib" > else > diff --git a/libgcobol/configure.ac b/libgcobol/configure.ac > index 5ca7b12776d..7396a2e3527 100644 > --- a/libgcobol/configure.ac > +++ b/libgcobol/configure.ac > @@ -195,6 +195,9 @@ case $host in > esac > AC_SUBST(extra_ldflags_libgcobol) > > +# These are GLIBC > +AC_CHECK_FUNCS_ONCE(random_r srandom_r initstate_r setstate_r) > + > if test "${multilib}" = "yes"; then > multilib_arg="--enable-multilib" > else > diff --git a/libgcobol/intrinsic.cc b/libgcobol/intrinsic.cc > index e3d255a29d6..b7e94f3b0d6 100644 > --- a/libgcobol/intrinsic.cc > +++ b/libgcobol/intrinsic.cc > @@ -3408,9 +3408,13 @@ __gg__trim( cblc_field_t *dest, > } > } > > +#if HAVE_INITSTATE_R && HAVE_SRANDOM_R && HAVE_RANDOM_R > static struct random_data *buf = NULL; > static char *state = NULL; > static const size_t state_len = 256; > +#else > +static unsigned seed = 0; > +#endif > > extern "C" > void > @@ -3419,6 +3423,9 @@ __gg__random( cblc_field_t *dest, > size_t input_offset, > size_t input_size) > { > + int32_t retval_31; > + int rdigits; > +#if HAVE_INITSTATE_R && HAVE_SRANDOM_R && HAVE_RANDOM_R > // This creates a thread-safe pseudo-random number generator > // using input as the seed > > @@ -3435,16 +3442,21 @@ __gg__random( cblc_field_t *dest, > __gg__clock_gettime(CLOCK_REALTIME, &ts); > initstate_r( ts.tv_nsec, state, state_len, buf); > } > - > - int rdigits; > int seed = (int)__gg__binary_value_from_qualified_field(&rdigits, > input, > input_offset, > input_size); > srandom_r(seed, buf); > > - int32_t retval_31; > random_r(buf, &retval_31); > +#else > + seed = (unsigned)__gg__binary_value_from_qualified_field(&rdigits, > + input, > + input_offset, > + input_size); > + srandom (seed); > + retval_31 = random (); > +#endif > // We are going to convert this to a value between zero and not quite > one: > double retval = double(retval_31) / double(0x80000000UL); > __gg__double_to_target( dest, > @@ -3456,6 +3468,8 @@ extern "C" > void > __gg__random_next(cblc_field_t *dest) > { > + int32_t retval_31; > +#if HAVE_INITSTATE_R && HAVE_SRANDOM_R && HAVE_RANDOM_R > // The return value is between zero and not quite one > > if( !buf ) > @@ -3468,9 +3482,10 @@ __gg__random_next(cblc_field_t *dest) > __gg__clock_gettime(CLOCK_REALTIME, &ts); > initstate_r( ts.tv_nsec, state, state_len, buf); > } > - int32_t retval_31; > random_r(buf, &retval_31); > - > +#else > + retval_31 = random (); > +#endif > // We are going to convert this to a value between zero and not quite > one: > double retval = double(retval_31) / double(0x80000000UL); > __gg__double_to_target( dest, > -- > 2.39.2 (Apple Git-143)