changeset 9898:02bfc9acab82

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. Signed-off-by: Eric Blake <ebb9@byu.net>
author Eric Blake <ebb9@byu.net>
date Sat, 12 Apr 2008 07:22:40 -0600
parents ebc67bd296ad
children 1e9793d6008a
files ChangeLog doc/posix-headers/math.texi lib/math.in.h m4/math_h.m4 m4/strtod.m4 modules/math tests/test-math.c
diffstat 7 files changed, 72 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- 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.
--- a/doc/posix-headers/math.texi
+++ b/doc/posix-headers/math.texi
@@ -9,7 +9,17 @@
 @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:
--- a/lib/math.in.h
+++ b/lib/math.in.h
@@ -1,6 +1,6 @@
 /* A GNU-like <math.h>.
 
-   Copyright (C) 2002-2003, 2007, 2008 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 @@
 
 /* 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 @@
 # 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
--- a/m4/math_h.m4
+++ b/m4/math_h.m4
@@ -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_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 @@
   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])
--- a/m4/strtod.m4
+++ b/m4/strtod.m4
@@ -25,7 +25,8 @@
     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;
   }
   {
--- a/modules/math
+++ b/modules/math
@@ -58,8 +58,10 @@
 	      -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' \
--- a/tests/test-math.c
+++ b/tests/test-math.c
@@ -43,7 +43,11 @@
 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;
 }