On NetBSD 9.3/arm64, I see this test failure: $ ./test-modfl ../../gltests/test-modfl.c:48: assertion 'y >= 0.972406759L && y <= 0.972406761L' failed
Here x=5.97241, y=1.97241, z=4 instead of the expected x=5.97241, y=0.97241, z=5. This patch provides a workaround. 2024-01-18 Bruno Haible <br...@clisp.org> modfl: Work around bug on NetBSD 9.3/arm64. * m4/modfl.m4 (gl_FUNC_MODFL): Add test whether modfl basically works. * doc/posix-functions/modfl.texi: Mention the NetBSD bug. diff --git a/doc/posix-functions/modfl.texi b/doc/posix-functions/modfl.texi index e789de26af..6a8a3ef476 100644 --- a/doc/posix-functions/modfl.texi +++ b/doc/posix-functions/modfl.texi @@ -14,6 +14,9 @@ @item This function is only defined as a macro with arguments on some platforms: MSVC 14. +@item +This function produces wrong results on some platforms: +NetBSD 9.3/arm64. @end itemize Portability problems fixed by Gnulib module @code{modfl-ieee}: diff --git a/m4/modfl.m4 b/m4/modfl.m4 index b205f9f5a5..b22ecf178b 100644 --- a/m4/modfl.m4 +++ b/m4/modfl.m4 @@ -1,4 +1,4 @@ -# modfl.m4 serial 12 +# modfl.m4 serial 13 dnl Copyright (C) 2011-2024 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -19,7 +19,51 @@ AC_DEFUN([gl_FUNC_MODFL] gl_MATHFUNC([modfl], [long double], [(long double, long double *)]) if test $gl_cv_func_modfl_no_libm = yes \ || test $gl_cv_func_modfl_in_libm = yes; then - : + AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles + AC_CACHE_CHECK([whether modfl works], + [gl_cv_func_modfl_works], + [ + saved_LIBS="$LIBS" + LIBS="$LIBS $MODFL_LIBM" + AC_RUN_IFELSE( + [AC_LANG_SOURCE([[ +#ifndef __NO_MATH_INLINES +# define __NO_MATH_INLINES 1 /* for glibc */ +#endif +#include <math.h> +static long double dummy (long double x, long double *iptr) { return 0; } +int main (int argc, char *argv[]) +{ + long double (* volatile my_modfl) (long double, long double *) = argc ? modfl : dummy; + long double i; + long double f; + /* Test modfl(5.972406760L,...). + This test fails on NetBSD 9.3/arm64. */ + f = my_modfl (5.972406760L, &i); + if (!(f < 1.0L && i == 5.0L)) + return 1; + return 0; +} + ]])], + [gl_cv_func_modfl_works=yes], + [gl_cv_func_modfl_works=no], + [case "$host_os" in + # Guess yes on glibc systems. + *-gnu* | gnu*) gl_cv_func_modfl_works="guessing yes" ;; + # Guess yes on musl systems. + *-musl* | midipix*) gl_cv_func_modfl_works="guessing yes" ;; + # Guess yes on native Windows. + mingw* | windows*) gl_cv_func_modfl_works="guessing yes" ;; + # If we don't know, obey --enable-cross-guesses. + *) gl_cv_func_modfl_works="$gl_cross_guess_normal" ;; + esac + ]) + LIBS="$saved_LIBS" + ]) + case "$gl_cv_func_modfl_works" in + *yes) ;; + *) REPLACE_MODFL=1 ;; + esac m4_ifdef([gl_FUNC_MODFL_IEEE], [ if test $gl_modfl_required = ieee && test $REPLACE_MODFL = 0; then AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles