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)

Reply via email to