Work around bugs in the system's isnanf on IRIX and Solaris.
authorBruno Haible <bruno@clisp.org>
Sat, 19 May 2007 23:54:48 +0000 (23:54 +0000)
committerBruno Haible <bruno@clisp.org>
Sat, 19 May 2007 23:54:48 +0000 (23:54 +0000)
ChangeLog
lib/isnan.c
m4/isnanf.m4

index 77b3af7..c2803fa 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,12 @@
 2007-05-19  Bruno Haible  <bruno@clisp.org>
 
+       * m4/isnanf.m4 (gl_ISNANF_WORKS): New macro.
+       (gl_FUNC_ISNANF_NO_LIBM): Invoke it.
+       * lib/isnan.c (FUNC): Use run-time expressions for SGI compiler.
+       Needed for IRIX 6.5 and Solaris 2.5.1.
+
+2007-05-19  Bruno Haible  <bruno@clisp.org>
+
        * tests/test-vasnprintf-posix.c (have_minus_zero): New function.
        (test_function): Skip tests involving -0.0 on platforms where
        -0.0 = 0.0.
index 3245714..daa4b52 100644 (file)
@@ -74,11 +74,12 @@ FUNC (DOUBLE x)
 #ifdef KNOWN_EXPBIT0_LOCATION
   /* Be careful to not do any floating-point operation on x, such as x == x,
      because x may be a signaling NaN.  */
-# if defined __SUNPRO_C || defined __DECC
+# if defined __SUNPRO_C || defined __DECC || (defined __sgi && !defined __GNUC__)
   /* The Sun C 5.0 compilers and the Compaq (ex-DEC) 6.4 compilers don't
      recognize the initializers as constant expressions.  The latter compiler
      also fails when constant-folding 0.0 / 0.0 even when constant-folding is
-     not required.  */
+     not required.  The SGI MIPSpro C compiler complains about "floating-point
+     operation result is out of range".  */
   static DOUBLE zero = L_(0.0);
   memory_double nan;
   DOUBLE plus_inf = L_(1.0) / L_(0.0);
index ddc17a8..03ab66b 100644 (file)
@@ -1,4 +1,4 @@
-# isnanf.m4 serial 1
+# isnanf.m4 serial 2
 dnl Copyright (C) 2007 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -10,6 +10,10 @@ AC_DEFUN([gl_FUNC_ISNANF_NO_LIBM],
 [
   gl_HAVE_ISNANF_NO_LIBM
   if test $gl_cv_func_isnanf_no_libm = yes; then
+    gl_ISNANF_WORKS
+  fi
+  if test $gl_cv_func_isnanf_no_libm = yes \
+     && test $gl_cv_func_isnanf_works = yes; then
     AC_DEFINE([HAVE_ISNANF_IN_LIBC], 1,
       [Define if the isnan(float) function is available in libc.])
   else
@@ -36,6 +40,47 @@ AC_DEFUN([gl_HAVE_ISNANF_NO_LIBM],
     ])
 ])
 
+dnl Test whether isnanf() recognizes a NaN (this fails on IRIX 6.5) and rejects
+dnl Infinity (this fails on Solaris 2.5.1).
+AC_DEFUN([gl_ISNANF_WORKS],
+[
+  AC_REQUIRE([AC_PROG_CC])
+  AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
+  AC_CACHE_CHECK([whether isnanf works], [gl_cv_func_isnanf_works],
+    [
+      AC_TRY_RUN([
+#include <math.h>
+#ifdef isnan
+# undef isnanf
+# define isnanf(x) isnan ((float)(x))
+#endif
+/* The Compaq (ex-DEC) C 6.4 compiler chokes on the expression 0.0 / 0.0.  */
+#ifdef __DECC
+static float
+NaN ()
+{
+  static float zero = 0.0f;
+  return zero / zero;
+}
+#else
+# define NaN() (0.0f / 0.0f)
+#endif
+int main()
+{
+  if (!isnanf (NaN ()))
+    return 1;
+  if (isnanf (1.0f / 0.0f))
+    return 1;
+  return 0;
+}], [gl_cv_func_isnanf_works=yes], [gl_cv_func_isnanf_works=no],
+        [case "$host_os" in
+           irix* | solaris*) gl_cv_func_isnanf_works="guessing no";;
+           *)                gl_cv_func_isnanf_works="guessing yes";;
+         esac
+        ])
+    ])
+])
+
 AC_DEFUN([gl_FLOAT_EXPONENT_LOCATION],
 [
   AC_CACHE_CHECK([where to find the exponent in a 'float'],