From 833333f7edfb45487d4a2cbae9f5e611c0c542cf Mon Sep 17 00:00:00 2001 From: Eric Blake Date: Sat, 12 Apr 2008 07:22:40 -0600 Subject: [PATCH] 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 --- ChangeLog | 12 ++++++++++++ doc/posix-headers/math.texi | 12 +++++++++++- lib/math.in.h | 16 +++++++++++++--- m4/math_h.m4 | 29 ++++++++++++++++++++++++++++- m4/strtod.m4 | 3 ++- modules/math | 2 ++ tests/test-math.c | 4 ++++ 7 files changed, 72 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index d3de184f6..3a150155d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2008-04-12 Eric Blake + + 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 Adapt to future versions of Apple GCC. diff --git a/doc/posix-headers/math.texi b/doc/posix-headers/math.texi index a7c8df77c..a0fa6aaff 100644 --- a/doc/posix-headers/math.texi +++ b/doc/posix-headers/math.texi @@ -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: diff --git a/lib/math.in.h b/lib/math.in.h index bb715aeea..c2b8b8107 100644 --- a/lib/math.in.h +++ b/lib/math.in.h @@ -1,6 +1,6 @@ /* A GNU-like . - 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 @@ 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 diff --git a/m4/math_h.m4 b/m4/math_h.m4 index dd99e7f2d..3090b6e86 100644 --- 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_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 ], + [[/* 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 ], + [[/* 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]) diff --git a/m4/strtod.m4 b/m4/strtod.m4 index 512746663..ba411a93b 100644 --- a/m4/strtod.m4 +++ b/m4/strtod.m4 @@ -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; } { diff --git a/modules/math b/modules/math index 9559865d7..62434f271 100644 --- a/modules/math +++ b/modules/math @@ -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' \ diff --git a/tests/test-math.c b/tests/test-math.c index ec654b260..aa51f8581 100644 --- a/tests/test-math.c +++ b/tests/test-math.c @@ -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; } -- 2.11.0