changeset 17644:bfa6d7414863

expl: avoid incorrect expl(small_value) on OpenBSD 5.4 OpenBSD 5.4, expl() incorrectly returns 'nan' for small values. Detect this and use gnulib's expl() in that case. Discussed here: http://marc.info/?t=139159081700002&r=1&w=2 (Message from David Coppa on 2014-02-05 to openbsd-tech mailing list). Fixed here (in revision 1.2): http://www.openbsd.org/cgi-bin/cvsweb/src/lib/libm/src/ld128/s_floorl.c * m4/expl.m4 (gl_FUNC_EXPL): Add a check for this condition. * doc/posix-functions/expl.texi: Mention the workaround.
author Assaf Gordon <agordon@wi.mit.edu>
date Wed, 16 Apr 2014 11:35:55 -0400
parents eaa841a1f670
children d746f88add8b
files ChangeLog doc/posix-functions/expl.texi m4/expl.m4
diffstat 3 files changed, 37 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Sat Apr 12 10:45:47 2014 -0700
+++ b/ChangeLog	Wed Apr 16 11:35:55 2014 -0400
@@ -1,3 +1,9 @@
+2014-04-16  Assaf Gordon  <agordon@wi.mit.edu>
+
+	expl: avoid incorrect expl(small_value) on OpenBSD 5.4
+	* m4/expl.m4 (gl_FUNC_EXPL): Add a check for this condition.
+	* doc/posix-functions/expl.texi: Mention the workaround.
+
 2014-04-12  Paul Eggert  <eggert@cs.ucla.edu>
 
 	xalloc: allow x2nrealloc (P, PN, S) where P && !*PN
--- a/doc/posix-functions/expl.texi	Sat Apr 12 10:45:47 2014 -0700
+++ b/doc/posix-functions/expl.texi	Wed Apr 16 11:35:55 2014 -0400
@@ -12,6 +12,9 @@
 This function is missing on some platforms:
 FreeBSD 6.0, NetBSD 5.0, OpenBSD 3.8, Minix 3.1.8, HP-UX 11, IRIX 6.5, Solaris 9, Cygwin, Interix 3.5, BeOS.
 @item
+This function returns NaN for small operands:
+OpenBSD 5.4.
+@item
 This function is only defined as a macro with arguments on some platforms:
 MSVC 9.
 @item
--- a/m4/expl.m4	Sat Apr 12 10:45:47 2014 -0700
+++ b/m4/expl.m4	Wed Apr 16 11:35:55 2014 -0400
@@ -53,6 +53,34 @@
       EXPL_LIBM=-lm
     fi
   fi
+  dnl On OpenBSD5.4 the system's native expl() is buggy:
+  dnl it returns 'nan' for small values. Test for this anomaly.
+  if test $gl_cv_func_expl_no_libm = yes \
+     || test $gl_cv_func_expl_in_libm = yes; then
+    AC_CACHE_CHECK([whether expl() breaks with small values],
+        [gl_cv_func_expl_buggy],
+        [
+          save_LIBS="$LIBS"
+          LIBS="$EXPL_LIBM"
+          AC_RUN_IFELSE(
+           [AC_LANG_PROGRAM(
+             [[#include <math.h>]],
+             [[return isnan(expl(-1.0))||
+                      isnan(expl(-0.8))||
+                      isnan(expl(-0.4)); ]])],
+             [gl_cv_func_expl_buggy=no], [gl_cv_func_expl_buggy=yes],
+             [case $host_os in
+                openbsd*) gl_cv_func_expl_buggy="guessing yes";;
+                *) gl_cv_func_expl_buggy="guessing no";;
+              esac])
+          LIBS="$save_LIBS"
+        ])
+    case "$gl_cv_func_expl_buggy" in
+      *yes)
+        gl_cv_func_expl_in_libm=no
+        gl_cv_func_expl_no_libm=no ;;
+    esac
+  fi
   if test $gl_cv_func_expl_no_libm = yes \
      || test $gl_cv_func_expl_in_libm = yes; then
     dnl Also check whether it's declared.