[Python-checkins] bpo-45440: Require math.h isinf() to build (GH-28894)

vstinner webhook-mailer at python.org
Wed Oct 13 17:27:58 EDT 2021


https://github.com/python/cpython/commit/194a9526d8ee6abbbe58ef48520ec87a7e83f327
commit: 194a9526d8ee6abbbe58ef48520ec87a7e83f327
branch: main
author: Victor Stinner <vstinner at python.org>
committer: vstinner <vstinner at python.org>
date: 2021-10-13T23:27:50+02:00
summary:

bpo-45440: Require math.h isinf() to build (GH-28894)

Building Python now requires a C99 <math.h> header file providing
isinf(), isnan() and isfinite() functions.

Remove the Py_FORCE_DOUBLE() macro. It was used by the
Py_IS_INFINITY() macro.

Changes:

* Remove Py_IS_NAN(), Py_IS_INFINITY() and Py_IS_FINITE()
  in PC/pyconfig.h.
* Remove the _Py_force_double() function.
* configure no longer checks if math.h defines isinf(), isnan() and
  isfinite().

files:
A Misc/NEWS.d/next/Build/2021-10-12-02-13-08.bpo-45440.-zYgDb.rst
A Misc/NEWS.d/next/C API/2021-10-12-02-13-41.bpo-45440.Gf94rE.rst
M Doc/whatsnew/3.11.rst
M Include/internal/pycore_pymath.h
M Include/pymath.h
M PC/pyconfig.h
M Python/pymath.c
M configure
M configure.ac
M pyconfig.h.in

diff --git a/Doc/whatsnew/3.11.rst b/Doc/whatsnew/3.11.rst
index d18711d0b8df2..48d454d9aac99 100644
--- a/Doc/whatsnew/3.11.rst
+++ b/Doc/whatsnew/3.11.rst
@@ -460,6 +460,10 @@ Build Changes
 * libpython is no longer linked against libcrypt.
   (Contributed by Mike Gilbert in :issue:`45433`.)
 
+* Building Python now requires a C99 ``<math.h>`` header file providing
+  ``isinf()``, ``isnan()`` and ``isfinite()`` functions.
+  (Contributed by Victor Stinner in :issue:`45440`.)
+
 C API Changes
 =============
 
@@ -605,3 +609,7 @@ Removed
 * Remove the ``pystrhex.h`` header file. It only contains private functions.
   C extensions should only include the main ``<Python.h>`` header file.
   (Contributed by Victor Stinner in :issue:`45434`.)
+
+* Remove the ``Py_FORCE_DOUBLE()`` macro. It was used by the
+  ``Py_IS_INFINITY()`` macro.
+  (Contributed by Victor Stinner in :issue:`45440`.)
diff --git a/Include/internal/pycore_pymath.h b/Include/internal/pycore_pymath.h
index 38f76d0461a89..32743fc83f5c0 100644
--- a/Include/internal/pycore_pymath.h
+++ b/Include/internal/pycore_pymath.h
@@ -142,6 +142,9 @@ extern void _Py_set_387controlword(unsigned short);
 // Get and set x87 control word for VisualStudio/x86.
 // x87 is not supported in 64-bit or ARM.
 #if defined(_MSC_VER) && !defined(_WIN64) && !defined(_M_ARM)
+
+#include <float.h>                // __control87_2()
+
 #define _Py_SET_53BIT_PRECISION_HEADER \
     unsigned int old_387controlword, new_387controlword, out_387controlword
     // We use the __control87_2 function to set only the x87 control word.
diff --git a/Include/pymath.h b/Include/pymath.h
index d688e5033e0cc..57310fc097e73 100644
--- a/Include/pymath.h
+++ b/Include/pymath.h
@@ -4,8 +4,6 @@
 #ifndef Py_PYMATH_H
 #define Py_PYMATH_H
 
-#include "pyconfig.h"             // HAVE_DECL_ISNAN
-
 /* High precision definition of pi and e (Euler)
  * The values are taken from libc6's math.h.
  */
@@ -29,77 +27,17 @@
 #define Py_MATH_TAU 6.2831853071795864769252867665590057683943L
 #endif
 
+// Py_IS_NAN(X)
+// Return 1 if float or double arg is a NaN, else 0.
+#define Py_IS_NAN(X) isnan(X)
 
-/* On x86, Py_FORCE_DOUBLE forces a floating-point number out of an x87 FPU
-   register and into a 64-bit memory location, rounding from extended
-   precision to double precision in the process.  On other platforms it does
-   nothing. */
-
-/* we take double rounding as evidence of x87 usage */
-#ifndef Py_LIMITED_API
-#ifndef Py_FORCE_DOUBLE
-#  ifdef X87_DOUBLE_ROUNDING
-PyAPI_FUNC(double) _Py_force_double(double);
-#    define Py_FORCE_DOUBLE(X) (_Py_force_double(X))
-#  else
-#    define Py_FORCE_DOUBLE(X) (X)
-#  endif
-#endif
-#endif
-
-/* Py_IS_NAN(X)
- * Return 1 if float or double arg is a NaN, else 0.
- * Caution:
- *     X is evaluated more than once.
- *     This may not work on all platforms.  Each platform has *some*
- *     way to spell this, though -- override in pyconfig.h if you have
- *     a platform where it doesn't work.
- * Note: PC/pyconfig.h defines Py_IS_NAN as _isnan
- */
-#ifndef Py_IS_NAN
-#  if defined HAVE_DECL_ISNAN && HAVE_DECL_ISNAN == 1
-#    define Py_IS_NAN(X) isnan(X)
-#  else
-#    define Py_IS_NAN(X) ((X) != (X))
-#  endif
-#endif
-
-/* Py_IS_INFINITY(X)
- * Return 1 if float or double arg is an infinity, else 0.
- * Caution:
- *    X is evaluated more than once.
- *    This implementation may set the underflow flag if |X| is very small;
- *    it really can't be implemented correctly (& easily) before C99.
- *    Override in pyconfig.h if you have a better spelling on your platform.
- *  Py_FORCE_DOUBLE is used to avoid getting false negatives from a
- *    non-infinite value v sitting in an 80-bit x87 register such that
- *    v becomes infinite when spilled from the register to 64-bit memory.
- * Note: PC/pyconfig.h defines Py_IS_INFINITY as _isinf
- */
-#ifndef Py_IS_INFINITY
-#  if defined HAVE_DECL_ISINF && HAVE_DECL_ISINF == 1
-#    define Py_IS_INFINITY(X) isinf(X)
-#  else
-#    define Py_IS_INFINITY(X) ((X) &&                                   \
-                               (Py_FORCE_DOUBLE(X)*0.5 == Py_FORCE_DOUBLE(X)))
-#  endif
-#endif
+// Py_IS_INFINITY(X)
+// Return 1 if float or double arg is an infinity, else 0.
+#define Py_IS_INFINITY(X) isinf(X)
 
-/* Py_IS_FINITE(X)
- * Return 1 if float or double arg is neither infinite nor NAN, else 0.
- * Some compilers (e.g. VisualStudio) have intrinsics for this, so a special
- * macro for this particular test is useful
- * Note: PC/pyconfig.h defines Py_IS_FINITE as _finite
- */
-#ifndef Py_IS_FINITE
-#  if defined HAVE_DECL_ISFINITE && HAVE_DECL_ISFINITE == 1
-#    define Py_IS_FINITE(X) isfinite(X)
-#  elif defined HAVE_FINITE
-#    define Py_IS_FINITE(X) finite(X)
-#  else
-#    define Py_IS_FINITE(X) (!Py_IS_INFINITY(X) && !Py_IS_NAN(X))
-#  endif
-#endif
+// Py_IS_FINITE(X)
+// Return 1 if float or double arg is neither infinite nor NAN, else 0.
+#define Py_IS_FINITE(X) isfinite(X)
 
 /* HUGE_VAL is supposed to expand to a positive double infinity.  Python
  * uses Py_HUGE_VAL instead because some platforms are broken in this
diff --git a/Misc/NEWS.d/next/Build/2021-10-12-02-13-08.bpo-45440.-zYgDb.rst b/Misc/NEWS.d/next/Build/2021-10-12-02-13-08.bpo-45440.-zYgDb.rst
new file mode 100644
index 0000000000000..1c7c413155f45
--- /dev/null
+++ b/Misc/NEWS.d/next/Build/2021-10-12-02-13-08.bpo-45440.-zYgDb.rst
@@ -0,0 +1,2 @@
+Building Python now requires a C99 ``<math.h>`` header file providing
+``isinf()``, ``isnan()`` and ``isfinite()`` functions. Patch by Victor Stinner.
diff --git a/Misc/NEWS.d/next/C API/2021-10-12-02-13-41.bpo-45440.Gf94rE.rst b/Misc/NEWS.d/next/C API/2021-10-12-02-13-41.bpo-45440.Gf94rE.rst
new file mode 100644
index 0000000000000..d9d695fd2ace4
--- /dev/null
+++ b/Misc/NEWS.d/next/C API/2021-10-12-02-13-41.bpo-45440.Gf94rE.rst	
@@ -0,0 +1,2 @@
+Remove the ``Py_FORCE_DOUBLE()`` macro. It was used by the ``Py_IS_INFINITY()``
+macro. Patch by Victor Stinner.
diff --git a/PC/pyconfig.h b/PC/pyconfig.h
index 012a89aab2bc8..75397772280dc 100644
--- a/PC/pyconfig.h
+++ b/PC/pyconfig.h
@@ -189,11 +189,6 @@ typedef _W64 int Py_ssize_t;
 
 typedef int pid_t;
 
-#include <float.h>
-#define Py_IS_NAN _isnan
-#define Py_IS_INFINITY(X) (!_finite(X) && !_isnan(X))
-#define Py_IS_FINITE(X) _finite(X)
-
 /* define some ANSI types that are not defined in earlier Win headers */
 #if _MSC_VER >= 1200
 /* This file only exists in VC 6.0 or higher */
@@ -358,15 +353,9 @@ Py_NO_ENABLE_SHARED to find out.  Also support MS_NO_COREDLL for b/w compat */
 
 /* Define to 1 if you have the `round' function. */
 #if _MSC_VER >= 1800
-#define HAVE_ROUND 1
+#  define HAVE_ROUND 1
 #endif
 
-/* Define to 1 if you have the `isinf' macro. */
-#define HAVE_DECL_ISINF 1
-
-/* Define to 1 if you have the `isnan' function. */
-#define HAVE_DECL_ISNAN 1
-
 /* Define if on AIX 3.
    System headers sometimes define this.
    We just want to avoid a redefinition error message.  */
diff --git a/Python/pymath.c b/Python/pymath.c
index d3c52a09650c5..b2681f2acc1f0 100644
--- a/Python/pymath.c
+++ b/Python/pymath.c
@@ -1,18 +1,5 @@
 #include "Python.h"
 
-#ifdef X87_DOUBLE_ROUNDING
-/* On x86 platforms using an x87 FPU, this function is called from the
-   Py_FORCE_DOUBLE macro (defined in pymath.h) to force a floating-point
-   number out of an 80-bit x87 FPU register and into a 64-bit memory location,
-   thus rounding from extended precision to double precision. */
-double _Py_force_double(double x)
-{
-    volatile double y;
-    y = x;
-    return y;
-}
-#endif
-
 
 #ifdef HAVE_GCC_ASM_FOR_X87
 // Inline assembly for getting and setting the 387 FPU control word on
diff --git a/configure b/configure
index b2d1a64206cd4..c56ff1dc5cd6a 100755
--- a/configure
+++ b/configure
@@ -15090,40 +15090,6 @@ _ACEOF
 fi
 done
 
-ac_fn_c_check_decl "$LINENO" "isinf" "ac_cv_have_decl_isinf" "#include <math.h>
-"
-if test "x$ac_cv_have_decl_isinf" = xyes; then :
-  ac_have_decl=1
-else
-  ac_have_decl=0
-fi
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE_DECL_ISINF $ac_have_decl
-_ACEOF
-ac_fn_c_check_decl "$LINENO" "isnan" "ac_cv_have_decl_isnan" "#include <math.h>
-"
-if test "x$ac_cv_have_decl_isnan" = xyes; then :
-  ac_have_decl=1
-else
-  ac_have_decl=0
-fi
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE_DECL_ISNAN $ac_have_decl
-_ACEOF
-ac_fn_c_check_decl "$LINENO" "isfinite" "ac_cv_have_decl_isfinite" "#include <math.h>
-"
-if test "x$ac_cv_have_decl_isfinite" = xyes; then :
-  ac_have_decl=1
-else
-  ac_have_decl=0
-fi
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE_DECL_ISFINITE $ac_have_decl
-_ACEOF
-
 
 # For multiprocessing module, check that sem_open
 # actually works.  For FreeBSD versions <= 7.2,
diff --git a/configure.ac b/configure.ac
index a6c6d1c49596a..1d0c753efac1a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -4677,7 +4677,6 @@ LIBS="$LIBS $LIBM"
 
 AC_CHECK_FUNCS([acosh asinh atanh copysign erf erfc expm1 finite gamma])
 AC_CHECK_FUNCS([hypot lgamma log1p log2 round tgamma])
-AC_CHECK_DECLS([isinf, isnan, isfinite], [], [], [[#include <math.h>]])
 
 # For multiprocessing module, check that sem_open
 # actually works.  For FreeBSD versions <= 7.2,
diff --git a/pyconfig.h.in b/pyconfig.h.in
index 3231cd68e063f..43a04e371a594 100644
--- a/pyconfig.h.in
+++ b/pyconfig.h.in
@@ -214,18 +214,6 @@
 /* Define if you have the 'wchgat' function. */
 #undef HAVE_CURSES_WCHGAT
 
-/* Define to 1 if you have the declaration of `isfinite', and to 0 if you
-   don't. */
-#undef HAVE_DECL_ISFINITE
-
-/* Define to 1 if you have the declaration of `isinf', and to 0 if you don't.
-   */
-#undef HAVE_DECL_ISINF
-
-/* Define to 1 if you have the declaration of `isnan', and to 0 if you don't.
-   */
-#undef HAVE_DECL_ISNAN
-
 /* Define to 1 if you have the declaration of `RTLD_DEEPBIND', and to 0 if you
    don't. */
 #undef HAVE_DECL_RTLD_DEEPBIND



More information about the Python-checkins mailing list