]> Savannah Git Hosting - gnulib.git/commitdiff
math: Fix INFINITY and NAN on FreeBSD and AIX.
authorBruno Haible <bruno@clisp.org>
Thu, 1 Aug 2024 14:41:23 +0000 (16:41 +0200)
committerBruno Haible <bruno@clisp.org>
Thu, 1 Aug 2024 14:41:23 +0000 (16:41 +0200)
* doc/posix-headers/math.texi: Mention some FreeBSD and AIX bugs.
* lib/math.in.h (INFINITY): New macro.
(NAN): Replace also on FreeBSD < 8 and AIX. Use __builtin_nanf where
available.
(HUGE_VALF): Replace also on FreeBSD < 6. Use __builtin_inff where
available.
(HUGE_VAL): Replace also on FreeBSD < 6. Use __builtin_inf where
available.
(HUGE_VALL): Replace also on FreeBSD < 6. Use __builtin_infl where
available.
* tests/test-math.c: Check that INFINITY, NAN, HUGE_VALF, HUGE_VAL,
HUGE_VALL are constant expressions.
(main): Check the type of INFINITY and NAN.

ChangeLog
doc/posix-headers/math.texi
lib/math.in.h
tests/test-math.c

index 964e07c9edb7f011f9a7e21e540614d239023581..55060e330ac44f48d2162a790935abef83ac2619 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,20 @@
+2024-08-01  Bruno Haible  <bruno@clisp.org>
+
+       math: Fix INFINITY and NAN on FreeBSD and AIX.
+       * doc/posix-headers/math.texi: Mention some FreeBSD and AIX bugs.
+       * lib/math.in.h (INFINITY): New macro.
+       (NAN): Replace also on FreeBSD < 8 and AIX. Use __builtin_nanf where
+       available.
+       (HUGE_VALF): Replace also on FreeBSD < 6. Use __builtin_inff where
+       available.
+       (HUGE_VAL): Replace also on FreeBSD < 6. Use __builtin_inf where
+       available.
+       (HUGE_VALL): Replace also on FreeBSD < 6. Use __builtin_infl where
+       available.
+       * tests/test-math.c: Check that INFINITY, NAN, HUGE_VALF, HUGE_VAL,
+       HUGE_VALL are constant expressions.
+       (main): Check the type of INFINITY and NAN.
+
 2024-08-01  Bruno Haible  <bruno@clisp.org>
 
        Ensure consistent effects of _LINUX_SOURCE_COMPAT.
index be7cad2759baaec5d39b3afd6db25bf08266c59b..92b4d1b1723e26b04189bf48464d2ca3d87f817c 100644 (file)
@@ -42,6 +42,21 @@ platforms:
 @c https://dev.haiku-os.org/ticket/18351
 Haiku 2022.
 
+@item
+@code{HUGE_VAL}, @code{HUGE_VALF}, @code{HUGE_VALL} are not compile time
+constants on some platforms:
+FreeBSD 5.2.
+
+@item
+@code{INFINITY} and @code{NAN} are not compile time constants
+on some platforms:
+FreeBSD 5.2, AIX 7.1.
+
+@item
+@code{INFINITY} and @code{NAN} are of type @code{double} instead of @code{float}
+on some platforms:
+FreeBSD 7.1.
+
 @item
 The macros @code{NAN}, @code{HUGE_VALL}, and @code{INFINITY} are not
 defined on some platforms:
index d3ecb74e69e49748bafa7551f4219a23df0e2f59..7730efb7f5b168eb97557728c70348901bdd7f5b 100644 (file)
@@ -160,12 +160,23 @@ static void (*_gl_math_fix_itold) (long double *, int) = _Qp_itoq;
 #endif
 
 
+/* Ensure that INFINITY is a constant expression, of type 'float'.  */
+#if !defined INFINITY || (defined __FreeBSD__ && __FreeBSD__ < 8) || defined _AIX
+# undef INFINITY
+# if defined __GNUC__ || defined __clang__
+#  define INFINITY (__builtin_inff ())
+# else
+#  define INFINITY (1.0f / 0.0f)
+# endif
+#endif
+
 /* 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.  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@
+   as a function pointer rather than a floating point constant.
+   Also ensure that it is a constant expression, of type 'float'.  */
+#if !defined NAN || @REPLACE_NAN@ || (defined __FreeBSD__ && __FreeBSD__ < 8) || defined _AIX
 # if !GNULIB_defined_NAN
 #  undef NAN
   /* The Compaq (ex-DEC) C 6.4 compiler and the Microsoft MSVC 9 compiler
@@ -178,6 +189,8 @@ _NaN ()
   return zero / zero;
 }
 #   define NAN (_NaN())
+#  elif defined __GNUC__ || defined __clang__
+#   define NAN (__builtin_nanf (""))
 #  else
 #   define NAN (0.0f / 0.0f)
 #  endif
@@ -197,30 +210,39 @@ _NaN ()
 #endif
 
 /* HUGE_VALF is a 'float' Infinity.  */
-#ifndef HUGE_VALF
+#if !defined HUGE_VALF || (defined __FreeBSD__ && __FreeBSD__ < 6)
+# undef HUGE_VALF
 # if defined _MSC_VER
 /* The Microsoft MSVC 9 compiler chokes on the expression 1.0f / 0.0f.  */
 #  define HUGE_VALF (1e25f * 1e25f)
+# elif defined __GNUC__ || defined __clang__
+#  define HUGE_VALF (__builtin_inff ())
 # else
 #  define HUGE_VALF (1.0f / 0.0f)
 # endif
 #endif
 
 /* HUGE_VAL is a 'double' Infinity.  */
-#ifndef HUGE_VAL
+#if !defined HUGE_VAL || (defined __FreeBSD__ && __FreeBSD__ < 6)
+# undef HUGE_VAL
 # if defined _MSC_VER
 /* The Microsoft MSVC 9 compiler chokes on the expression 1.0 / 0.0.  */
 #  define HUGE_VAL (1e250 * 1e250)
+# elif defined __GNUC__ || defined __clang__
+#  define HUGE_VAL (__builtin_inf ())
 # else
 #  define HUGE_VAL (1.0 / 0.0)
 # endif
 #endif
 
 /* HUGE_VALL is a 'long double' Infinity.  */
-#ifndef HUGE_VALL
+#if !defined HUGE_VALL || (defined __FreeBSD__ && __FreeBSD__ < 6)
+# undef HUGE_VALL
 # if defined _MSC_VER
 /* The Microsoft MSVC 9 compiler chokes on the expression 1.0L / 0.0L.  */
 #  define HUGE_VALL (1e250L * 1e250L)
+# elif defined __GNUC__ || defined __clang__
+#  define HUGE_VALL (__builtin_infl ())
 # else
 #  define HUGE_VALL (1.0L / 0.0L)
 # endif
index d33ec7e5e22506c0f7af2357bc779eb4b74aa92c..cfb510b933e39ebc78b93f58bff5f03797dcf67a 100644 (file)
 
 #include <math.h>
 
+#ifndef INFINITY
+# error INFINITY should be defined, added in ISO C 99
+choke me
+#endif
+
 #ifndef NAN
-# error NAN should be defined
+# error NAN should be defined, added in ISO C 99
 choke me
 #endif
 
@@ -50,10 +55,20 @@ choke me
 choke me
 #endif
 
-#if 0
+/* Check that INFINITY expands into a constant expression.  */
+float in = INFINITY;
+
 /* Check that NAN expands into a constant expression.  */
-static float n = NAN;
-#endif
+float na = NAN;
+
+/* Check that HUGE_VALF expands into a constant expression.  */
+float hf = HUGE_VALF;
+
+/* Check that HUGE_VAL expands into a constant expression.  */
+double hd = HUGE_VAL;
+
+/* Check that HUGE_VALL expands into a constant expression.  */
+long double hl = HUGE_VALL;
 
 #include <limits.h>
 
@@ -81,17 +96,28 @@ numeric_equall (long double x, long double y)
 int
 main (void)
 {
-  double d = NAN;
+  double d;
   double zero = 0.0;
-  ASSERT (!numeric_equald (d, d));
 
-  d = HUGE_VAL;
-  ASSERT (numeric_equald (d, 1.0 / zero));
+  /* Check that INFINITY is a float.  */
+  ASSERT (sizeof (INFINITY) == sizeof (float));
+
+  /* Check that NAN is a float.  */
+  ASSERT (sizeof (NAN) == sizeof (float));
 
+  /* Check the value of NAN.  */
+  d = NAN;
+  ASSERT (!numeric_equald (d, d));
+
+  /* Check the value of HUGE_VALF.  */
   ASSERT (numeric_equalf (HUGE_VALF, HUGE_VALF + HUGE_VALF));
 
+  /* Check the value of HUGE_VAL.  */
+  d = HUGE_VAL;
+  ASSERT (numeric_equald (d, 1.0 / zero));
   ASSERT (numeric_equald (HUGE_VAL, HUGE_VAL + HUGE_VAL));
 
+  /* Check the value of HUGE_VALL.  */
   ASSERT (numeric_equall (HUGE_VALL, HUGE_VALL + HUGE_VALL));
 
   /* Check the value of FP_ILOGB0.  */