Work around Solaris 10 math.h bug.
authorEric Blake <ebb9@byu.net>
Sat, 12 Apr 2008 13:22:40 +0000 (07:22 -0600)
committerEric Blake <ebb9@byu.net>
Sat, 12 Apr 2008 13:28:35 +0000 (07:28 -0600)
* m4/math_h.m4 (gl_MATH_H): Check for bug.
(gl_MATH_H_DEFAULTS): Set up default.
* modules/math (Makefile.am): Replace new indicators.
* lib/math.in.h (NAN, HUGE_VAL): Provide replacements.
* tests/test-math.c (main): Test this.
* m4/strtod.m4 (gl_FUNC_STRTOD): Don't rely on HUGE_VAL.
* doc/posix-headers/math.texi (math.h): Mention bug.
Reported by Nelson H. F. Beebe and Jim Meyering.

Signed-off-by: Eric Blake <ebb9@byu.net>
ChangeLog
doc/posix-headers/math.texi
lib/math.in.h
m4/math_h.m4
m4/strtod.m4
modules/math
tests/test-math.c

index d3de184f6c3f569c6208a694b1a734ad65c8e71b..3a150155d8eafbddcdb3331864b5f94658d414fc 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2008-04-12  Eric Blake  <ebb9@byu.net>
+
+       Work around Solaris 10 math.h bug.
+       * m4/math_h.m4 (gl_MATH_H): Check for bug.
+       (gl_MATH_H_DEFAULTS): Set up default.
+       * modules/math (Makefile.am): Replace new indicators.
+       * lib/math.in.h (NAN, HUGE_VAL): Provide replacements.
+       * tests/test-math.c (main): Test this.
+       * m4/strtod.m4 (gl_FUNC_STRTOD): Don't rely on HUGE_VAL.
+       * doc/posix-headers/math.texi (math.h): Mention bug.
+       Reported by Nelson H. F. Beebe and Jim Meyering.
+
 2008-04-11  Bruno Haible  <bruno@clisp.org>
 
        Adapt to future versions of Apple GCC.
index a7c8df77c209be6dd685798b758e1075a0801c61..a0fa6aaff97871035cdf74689f0c0fd6b8cda525 100644 (file)
@@ -9,7 +9,17 @@ Portability problems fixed by Gnulib:
 @itemize
 @item
 The macro @code{NAN} is not defined on some platforms:
-OpenBSD 4.0, AIX 5.1, IRIX 6.5, OSF/1 5.1, Solaris 10.
+OpenBSD 4.0, AIX 5.1, IRIX 6.5, OSF/1 5.1.
+
+@item
+The macro @code{NAN} is not exposed outside of C99 compilation on some
+platforms:
+glibc.
+
+@item
+The macros @code{NAN} and @code{HUGE_VAL} expand to a function address
+rather than a floating point constant on some platforms:
+Solaris 10.
 @end itemize
 
 Portability problems not fixed by Gnulib:
index bb715aeeaf525ed5acd9cb28547f8bd0937e7948..c2b8b81071c59656706b44667619522eec7477ba 100644 (file)
@@ -1,6 +1,6 @@
 /* A GNU-like <math.h>.
 
-   Copyright (C) 2002-2003, 20072008 Free Software Foundation, Inc.
+   Copyright (C) 2002-2003, 2007-2008 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -34,8 +34,11 @@ extern "C" {
 
 /* POSIX allows platforms that don't support NAN.  But all major
    machines in the past 15 years have supported something close to
-   IEEE NaN, so we define this unconditionally.  */
-#ifndef NAN
+   IEEE NaN, so we define this unconditionally.  We also must define
+   it on platforms like Solaris 10, where NAN is present but defined
+   as a function pointer rather than a floating point constant.  */
+#if !defined NAN || @REPLACE_NAN@
+# undef NAN
   /* The Compaq (ex-DEC) C 6.4 compiler chokes on the expression 0.0 / 0.0.  */
 # ifdef __DECC
 static float
@@ -50,6 +53,13 @@ _NaN ()
 # endif
 #endif
 
+/* Solaris 10 defines HUGE_VAL, but as a function pointer rather
+   than a floating point constant.  */
+#if @REPLACE_HUGE_VAL@
+# undef HUGE_VAL
+# define HUGE_VAL (1.0 / 0.0)
+#endif
+
 /* Write x as
      x = mantissa * 2^exp
    where
index dd99e7f2d7dabb7edece4bef06c0034de9688e71..3090b6e863ebc5fe33879bf2a3424238fd7e8684 100644 (file)
@@ -1,4 +1,4 @@
-# math_h.m4 serial 9
+# math_h.m4 serial 10
 dnl Copyright (C) 2007-2008 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -8,6 +8,31 @@ AC_DEFUN([gl_MATH_H],
 [
   AC_REQUIRE([gl_MATH_H_DEFAULTS])
   gl_CHECK_NEXT_HEADERS([math.h])
+  AC_CACHE_CHECK([whether NAN macro works], [gl_cv_header_math_nan_works],
+    [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([@%:@include <math.h>],
+      [[/* Solaris 10 has a broken definition of NAN.  Other platforms
+        fail to provide NAN, or provide it only in C99 mode; this
+        test only needs to fail when NAN is provided but wrong.  */
+         float f = 1.0f;
+#ifdef NAN
+        f = NAN;
+#endif
+        return f == 0;]])],
+      [gl_cv_header_math_nan_works=yes],
+      [gl_cv_header_math_nan_works=no])])
+  if test gl_cv_header_math_nan_works = no; then
+    REPLACE_NAN=1
+  fi
+  AC_CACHE_CHECK([whether HUGE_VAL works], [gl_cv_header_math_huge_val_works],
+    [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([@%:@include <math.h>],
+      [[/* Solaris 10 has a broken definition of HUGE_VAL.  */
+        double d = HUGE_VAL;
+        return d == 0;]])],
+      [gl_cv_header_math_huge_val_works=yes],
+      [gl_cv_header_math_huge_val_works=no])])
+  if test gl_cv_header_math_huge_val_works = no; then
+    REPLACE_HUGE_VAL=1
+  fi
 ])
 
 AC_DEFUN([gl_MATH_MODULE_INDICATOR],
@@ -56,8 +81,10 @@ AC_DEFUN([gl_MATH_H_DEFAULTS],
   REPLACE_FLOORL=0;            AC_SUBST([REPLACE_FLOORL])
   REPLACE_FREXP=0;             AC_SUBST([REPLACE_FREXP])
   REPLACE_FREXPL=0;            AC_SUBST([REPLACE_FREXPL])
+  REPLACE_HUGE_VAL=0;          AC_SUBST([REPLACE_HUGE_VAL])
   REPLACE_ISFINITE=0;          AC_SUBST([REPLACE_ISFINITE])
   REPLACE_LDEXPL=0;            AC_SUBST([REPLACE_LDEXPL])
+  REPLACE_NAN=0;               AC_SUBST([REPLACE_NAN])
   REPLACE_ROUND=0;             AC_SUBST([REPLACE_ROUND])
   REPLACE_ROUNDF=0;            AC_SUBST([REPLACE_ROUNDF])
   REPLACE_ROUNDL=0;            AC_SUBST([REPLACE_ROUNDL])
index 512746663afea0356a6cdb0fa852dbcec39c70d8..ba411a93ba9ab5def127356394a537e52523f765 100644 (file)
@@ -25,7 +25,8 @@ AC_DEFUN([gl_FUNC_STRTOD],
     const char *string = "-0x";
     char *term;
     double value = strtod (string, &term);
-    if (1 / value != -HUGE_VAL || term != (string + 2))
+    double zero = 0.0;
+    if (1.0 / value != -1.0 / zero || term != (string + 2))
       return 1;
   }
   {
index 9559865d72a723484b2ece83fb11515eaf230cc2..62434f271cfbdc491f216df5a748757be503488d 100644 (file)
@@ -58,8 +58,10 @@ math.h: math.in.h
              -e 's|@''REPLACE_FLOORL''@|$(REPLACE_FLOORL)|g' \
              -e 's|@''REPLACE_FREXP''@|$(REPLACE_FREXP)|g' \
              -e 's|@''REPLACE_FREXPL''@|$(REPLACE_FREXPL)|g' \
+             -e 's|@''REPLACE_HUGE_VAL''@|$(REPLACE_HUGE_VAL)|g' \
              -e 's|@''REPLACE_ISFINITE''@|$(REPLACE_ISFINITE)|g' \
              -e 's|@''REPLACE_LDEXPL''@|$(REPLACE_LDEXPL)|g' \
+             -e 's|@''REPLACE_NAN''@|$(REPLACE_NAN)|g' \
              -e 's|@''REPLACE_ROUND''@|$(REPLACE_ROUND)|g' \
              -e 's|@''REPLACE_ROUNDF''@|$(REPLACE_ROUNDF)|g' \
              -e 's|@''REPLACE_ROUNDL''@|$(REPLACE_ROUNDL)|g' \
index ec654b26010fcc497553b96fc71218d3356020eb..aa51f8581a3890389bfeea4c9d2461c6d611908f 100644 (file)
@@ -43,7 +43,11 @@ int
 main ()
 {
   double d = NAN;
+  double zero = 0.0;
   if (numeric_equal (d, d))
     return 1;
+  d = HUGE_VAL;
+  if (!numeric_equal (d, 1.0 / zero))
+    return 1;
   return 0;
 }