From: Eric Blake Date: Fri, 27 Feb 2009 03:18:42 +0000 (-0700) Subject: avoid gcc 3.4.3 bug on long double NaN on Irix 6.5 X-Git-Tag: v0.1~6262 X-Git-Url: http://erislabs.org.uk/gitweb/?a=commitdiff_plain;h=ecab4471c7da5d367a62c8db75ee54ed6d948e40;p=gnulib.git avoid gcc 3.4.3 bug on long double NaN on Irix 6.5 * tests/nan.h (NaNl): Rewrite as function on Irix, to avoid compilation bug by using runtime conversion. * m4/isfinite.m4 (gl_ISFINITE): Likewise. * m4/isnanl.m4 (gl_FUNC_ISNANL): Likewise. * modules/ceill-tests (Files): Use nan.h. * modules/floorl-tests (Files): Likewise. * modules/frexpl-tests (Files): Likewise. * modules/isnanl-tests (Files): Likewise. * modules/ldexpl-tests (Files): Likewise. * modules/roundl-tests (Files): Likewise. * modules/truncl-tests (Files): Likewise. * tests/test-ceill.c (main): Use a working NaN. * tests/test-floorl.c (main): Likewise. * tests/test-frexpl.c (main): Likewise. * tests/test-isnan.c (test_long_double): Likewise. * tests/test-isnanl.h (main): Likewise. * tests/test-ldexpl.h (main): Likewise. * tests/test-roundl.h (main): Likewise. * tests/test-truncl.h (main): Likewise. See http://lists.gnu.org/archive/html/bug-gnulib/2009-02/msg00190.html. Signed-off-by: Eric Blake --- diff --git a/ChangeLog b/ChangeLog index 583fa8f13..90f91f6cc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,29 @@ 2009-02-26 Eric Blake - Bruno Haible + + avoid gcc 3.4.3 bug on long double NaN on Irix 6.5 + * tests/nan.h (NaNl): Rewrite as function on Irix, to avoid + compilation bug by using runtime conversion. + * m4/isfinite.m4 (gl_ISFINITE): Likewise. + * m4/isnanl.m4 (gl_FUNC_ISNANL): Likewise. + * modules/ceill-tests (Files): Use nan.h. + * modules/floorl-tests (Files): Likewise. + * modules/frexpl-tests (Files): Likewise. + * modules/isnanl-tests (Files): Likewise. + * modules/ldexpl-tests (Files): Likewise. + * modules/roundl-tests (Files): Likewise. + * modules/truncl-tests (Files): Likewise. + * tests/test-ceill.c (main): Use a working NaN. + * tests/test-floorl.c (main): Likewise. + * tests/test-frexpl.c (main): Likewise. + * tests/test-isnan.c (test_long_double): Likewise. + * tests/test-isnanl.h (main): Likewise. + * tests/test-ldexpl.h (main): Likewise. + * tests/test-roundl.h (main): Likewise. + * tests/test-truncl.h (main): Likewise. + See http://lists.gnu.org/archive/html/bug-gnulib/2009-02/msg00190.html. + +2009-02-26 Eric Blake + Bruno Haible Work around a *printf bug with %ls on Solaris. * m4/printf.m4 (gl_PRINTF_DIRECTIVE_LS): Also test whether, when a diff --git a/m4/isfinite.m4 b/m4/isfinite.m4 index 055ba8237..019eb9590 100644 --- a/m4/isfinite.m4 +++ b/m4/isfinite.m4 @@ -1,4 +1,4 @@ -# isfinite.m4 serial 4 +# isfinite.m4 serial 5 dnl Copyright (C) 2007-2009 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -56,6 +56,17 @@ AC_DEFUN([gl_ISFINITEL_WORKS], ((sizeof (long double) + sizeof (unsigned int) - 1) / sizeof (unsigned int)) typedef union { unsigned int word[NWORDS]; long double value; } memory_long_double; +/* On Irix 6.5, gcc 3.4.3 can't compute compile-time NaN, and needs the + runtime type conversion. */ +#ifdef __sgi +static long double NaNl () +{ + double zero = 0.0; + return zero / zero; +} +#else +# define NaNl() (0.0L / 0.0L) +#endif int main () { memory_long_double m; @@ -65,7 +76,7 @@ int main () in the mantissa bits. The xor operation twiddles a bit that can only be a sign bit or a mantissa bit (since the exponent never extends to bit 31). */ - m.value = 0.0L / 0.0L; + m.value = NaNl (); m.word[NWORDS / 2] ^= (unsigned int) 1 << (sizeof (unsigned int) * CHAR_BIT - 1); for (i = 0; i < NWORDS; i++) m.word[i] |= 1; diff --git a/m4/isnanl.m4 b/m4/isnanl.m4 index fb63ac455..e3029f5c9 100644 --- a/m4/isnanl.m4 +++ b/m4/isnanl.m4 @@ -1,4 +1,4 @@ -# isnanl.m4 serial 11 +# isnanl.m4 serial 12 dnl Copyright (C) 2007-2009 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -133,20 +133,30 @@ AC_DEFUN([gl_FUNC_ISNANL_WORKS], ((sizeof (long double) + sizeof (unsigned int) - 1) / sizeof (unsigned int)) typedef union { unsigned int word[NWORDS]; long double value; } memory_long_double; +/* On Irix 6.5, gcc 3.4.3 can't compute compile-time NaN, and needs the + runtime type conversion. */ +#ifdef __sgi +static long double NaNl () +{ + double zero = 0.0; + return zero / zero; +} +#else +# define NaNl() (0.0L / 0.0L) +#endif int main () { memory_long_double m; unsigned int i; - /* gcc-3.4.3 on IRIX 6.5 appears to have a problem with this. */ - if (!isnanl (0.0L / 0.0L)) + if (!isnanl (NaNl ())) return 1; /* The isnanl function should be immune against changes in the sign bit and in the mantissa bits. The xor operation twiddles a bit that can only be a sign bit or a mantissa bit (since the exponent never extends to bit 31). */ - m.value = 0.0L / 0.0L; + m.value = NaNl (); m.word[NWORDS / 2] ^= (unsigned int) 1 << (sizeof (unsigned int) * CHAR_BIT - 1); for (i = 0; i < NWORDS; i++) m.word[i] |= 1; diff --git a/modules/ceill-tests b/modules/ceill-tests index 381b3a5ed..ab10141d2 100644 --- a/modules/ceill-tests +++ b/modules/ceill-tests @@ -1,5 +1,6 @@ Files: tests/test-ceill.c +tests/nan.h Depends-on: fpucw diff --git a/modules/floorl-tests b/modules/floorl-tests index 7aef91d24..ca7c7461f 100644 --- a/modules/floorl-tests +++ b/modules/floorl-tests @@ -1,5 +1,6 @@ Files: tests/test-floorl.c +tests/nan.h Depends-on: fpucw diff --git a/modules/frexpl-tests b/modules/frexpl-tests index 6291f4eb2..f5505b45d 100644 --- a/modules/frexpl-tests +++ b/modules/frexpl-tests @@ -1,5 +1,6 @@ Files: tests/test-frexpl.c +tests/nan.h Depends-on: fpucw diff --git a/modules/isnanl-tests b/modules/isnanl-tests index 7b4086e6e..518420faf 100644 --- a/modules/isnanl-tests +++ b/modules/isnanl-tests @@ -1,6 +1,7 @@ Files: tests/test-isnanl.c tests/test-isnanl.h +tests/nan.h Depends-on: float diff --git a/modules/ldexpl-tests b/modules/ldexpl-tests index 6c88bfdac..0b1ba0490 100644 --- a/modules/ldexpl-tests +++ b/modules/ldexpl-tests @@ -1,5 +1,6 @@ Files: tests/test-ldexpl.c +tests/nan.h Depends-on: fpucw diff --git a/modules/roundl-tests b/modules/roundl-tests index 8e329a5c2..442c279c7 100644 --- a/modules/roundl-tests +++ b/modules/roundl-tests @@ -1,5 +1,6 @@ Files: tests/test-roundl.c +tests/nan.h Depends-on: fpucw diff --git a/modules/truncl-tests b/modules/truncl-tests index 236585475..7ffc1cde6 100644 --- a/modules/truncl-tests +++ b/modules/truncl-tests @@ -1,5 +1,6 @@ Files: tests/test-truncl.c +tests/nan.h Depends-on: fpucw diff --git a/tests/nan.h b/tests/nan.h index 3bdf6438c..8aa8bf002 100644 --- a/tests/nan.h +++ b/tests/nan.h @@ -1,5 +1,5 @@ /* Macros for not-a-number. - Copyright (C) 2007-2008 Free Software Foundation, Inc. + Copyright (C) 2007-2009 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 @@ -47,4 +47,14 @@ NaNd () /* NaNl () returns a 'long double' not-a-number. */ -#define NaNl() (0.0L / 0.0L) +/* On Irix 6.5, gcc 3.4.3 can't compute compile-time NaN, and needs the + runtime type conversion. */ +#ifdef __sgi +static long double NaNl () +{ + double zero = 0.0; + return zero / zero; +} +#else +# define NaNl() (0.0L / 0.0L) +#endif diff --git a/tests/test-ceill.c b/tests/test-ceill.c index d1f0266c5..3d4c9e3e8 100644 --- a/tests/test-ceill.c +++ b/tests/test-ceill.c @@ -26,6 +26,7 @@ #include "fpucw.h" #include "isnanl-nolibm.h" +#include "nan.h" #define ASSERT(expr) \ do \ @@ -90,7 +91,7 @@ main () ASSERT (ceill (1.0L / 0.0L) == 1.0L / 0.0L); ASSERT (ceill (-1.0L / 0.0L) == -1.0L / 0.0L); /* NaNs. */ - ASSERT (isnanl (ceill (0.0L / 0.0L))); + ASSERT (isnanl (ceill (NaNl ()))); return 0; } diff --git a/tests/test-floorl.c b/tests/test-floorl.c index 14979e68d..87fea7f86 100644 --- a/tests/test-floorl.c +++ b/tests/test-floorl.c @@ -26,6 +26,7 @@ #include "fpucw.h" #include "isnanl-nolibm.h" +#include "nan.h" #define ASSERT(expr) \ do \ @@ -90,7 +91,7 @@ main () ASSERT (floorl (1.0L / 0.0L) == 1.0L / 0.0L); ASSERT (floorl (-1.0L / 0.0L) == -1.0L / 0.0L); /* NaNs. */ - ASSERT (isnanl (floorl (0.0L / 0.0L))); + ASSERT (isnanl (floorl (NaNl ()))); return 0; } diff --git a/tests/test-frexpl.c b/tests/test-frexpl.c index 2b968b8ee..d4babb88c 100644 --- a/tests/test-frexpl.c +++ b/tests/test-frexpl.c @@ -26,6 +26,7 @@ #include "fpucw.h" #include "isnanl-nolibm.h" +#include "nan.h" /* Avoid some warnings from "gcc -Wshadow". This file doesn't use the exp() function. */ @@ -95,7 +96,7 @@ main () { /* NaN. */ int exp = -9999; long double mantissa; - x = 0.0L / 0.0L; + x = NaNl (); mantissa = frexpl (x, &exp); ASSERT (isnanl (mantissa)); } diff --git a/tests/test-isnan.c b/tests/test-isnan.c index 61490176c..9a0856a0e 100644 --- a/tests/test-isnan.c +++ b/tests/test-isnan.c @@ -163,14 +163,14 @@ test_long_double (void) ASSERT (!isnan (1.0L / 0.0L)); ASSERT (!isnan (-1.0L / 0.0L)); /* Quiet NaN. */ - ASSERT (isnan (0.0L / 0.0L)); + ASSERT (isnan (NaNl ())); #if defined LDBL_EXPBIT0_WORD && defined LDBL_EXPBIT0_BIT /* A bit pattern that is different from a Quiet NaN. With a bit of luck, it's a Signalling NaN. */ { memory_long_double m; - m.value = 0.0L / 0.0L; + m.value = NaNl (); # if LDBL_EXPBIT0_BIT > 0 m.word[LDBL_EXPBIT0_WORD] ^= (unsigned int) 1 << (LDBL_EXPBIT0_BIT - 1); # else diff --git a/tests/test-isnanl.h b/tests/test-isnanl.h index 37e28579c..baf04db0d 100644 --- a/tests/test-isnanl.h +++ b/tests/test-isnanl.h @@ -21,6 +21,8 @@ #include #include +#include "nan.h" + #define ASSERT(expr) \ do \ { \ @@ -70,14 +72,14 @@ main () ASSERT (!isnanl (1.0L / 0.0L)); ASSERT (!isnanl (-1.0L / 0.0L)); /* Quiet NaN. */ - ASSERT (isnanl (0.0L / 0.0L)); + ASSERT (isnanl (NaNl ())); #if defined LDBL_EXPBIT0_WORD && defined LDBL_EXPBIT0_BIT /* A bit pattern that is different from a Quiet NaN. With a bit of luck, it's a Signalling NaN. */ { memory_long_double m; - m.value = 0.0L / 0.0L; + m.value = NaNl (); # if LDBL_EXPBIT0_BIT > 0 m.word[LDBL_EXPBIT0_WORD] ^= (unsigned int) 1 << (LDBL_EXPBIT0_BIT - 1); # else diff --git a/tests/test-ldexpl.c b/tests/test-ldexpl.c index 395c00fb0..5f1fbd99f 100644 --- a/tests/test-ldexpl.c +++ b/tests/test-ldexpl.c @@ -26,6 +26,7 @@ #include "fpucw.h" #include "isnanl-nolibm.h" +#include "nan.h" #define ASSERT(expr) \ do \ @@ -66,7 +67,7 @@ main () BEGIN_LONG_DOUBLE_ROUNDING (); { /* NaN. */ - x = 0.0L / 0.0L; + x = NaNl (); y = ldexpl (x, 0); ASSERT (isnanl (y)); y = ldexpl (x, 5); ASSERT (isnanl (y)); y = ldexpl (x, -5); ASSERT (isnanl (y)); diff --git a/tests/test-roundl.c b/tests/test-roundl.c index 51cd1cdd9..ddbf47444 100644 --- a/tests/test-roundl.c +++ b/tests/test-roundl.c @@ -28,6 +28,7 @@ #include "fpucw.h" #include "isnanl-nolibm.h" +#include "nan.h" #define ASSERT(expr) \ do \ @@ -97,7 +98,7 @@ main () ASSERT (roundl (1.0 / 0.0L) == 1.0 / 0.0L); ASSERT (roundl (-1.0 / 0.0L) == -1.0 / 0.0L); /* NaNs. */ - ASSERT (isnanl (roundl (0.0L / 0.0L))); + ASSERT (isnanl (roundl (NaNl ()))); return 0; } diff --git a/tests/test-truncl.c b/tests/test-truncl.c index aad677d6c..f8ce551e9 100644 --- a/tests/test-truncl.c +++ b/tests/test-truncl.c @@ -26,6 +26,7 @@ #include "fpucw.h" #include "isnanl-nolibm.h" +#include "nan.h" #define ASSERT(expr) \ do \ @@ -89,7 +90,7 @@ main () ASSERT (truncl (1.0L / 0.0L) == 1.0L / 0.0L); ASSERT (truncl (-1.0L / 0.0L) == -1.0L / 0.0L); /* NaNs. */ - ASSERT (isnanl (truncl (0.0L / 0.0L))); + ASSERT (isnanl (truncl (NaNl ()))); return 0; }