Skip to content

Commit 194a952

Browse files
authored
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().
1 parent aac29af commit 194a952

File tree

10 files changed

+25
-143
lines changed

10 files changed

+25
-143
lines changed

Doc/whatsnew/3.11.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -460,6 +460,10 @@ Build Changes
460460
* libpython is no longer linked against libcrypt.
461461
(Contributed by Mike Gilbert in :issue:`45433`.)
462462

463+
* Building Python now requires a C99 ``<math.h>`` header file providing
464+
``isinf()``, ``isnan()`` and ``isfinite()`` functions.
465+
(Contributed by Victor Stinner in :issue:`45440`.)
466+
463467
C API Changes
464468
=============
465469

@@ -605,3 +609,7 @@ Removed
605609
* Remove the ``pystrhex.h`` header file. It only contains private functions.
606610
C extensions should only include the main ``<Python.h>`` header file.
607611
(Contributed by Victor Stinner in :issue:`45434`.)
612+
613+
* Remove the ``Py_FORCE_DOUBLE()`` macro. It was used by the
614+
``Py_IS_INFINITY()`` macro.
615+
(Contributed by Victor Stinner in :issue:`45440`.)

Include/internal/pycore_pymath.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,9 @@ extern void _Py_set_387controlword(unsigned short);
142142
// Get and set x87 control word for VisualStudio/x86.
143143
// x87 is not supported in 64-bit or ARM.
144144
#if defined(_MSC_VER) && !defined(_WIN64) && !defined(_M_ARM)
145+
146+
#include <float.h> // __control87_2()
147+
145148
#define _Py_SET_53BIT_PRECISION_HEADER \
146149
unsigned int old_387controlword, new_387controlword, out_387controlword
147150
// We use the __control87_2 function to set only the x87 control word.

Include/pymath.h

Lines changed: 9 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@
44
#ifndef Py_PYMATH_H
55
#define Py_PYMATH_H
66

7-
#include "pyconfig.h" // HAVE_DECL_ISNAN
8-
97
/* High precision definition of pi and e (Euler)
108
* The values are taken from libc6's math.h.
119
*/
@@ -29,77 +27,17 @@
2927
#define Py_MATH_TAU 6.2831853071795864769252867665590057683943L
3028
#endif
3129

30+
// Py_IS_NAN(X)
31+
// Return 1 if float or double arg is a NaN, else 0.
32+
#define Py_IS_NAN(X) isnan(X)
3233

33-
/* On x86, Py_FORCE_DOUBLE forces a floating-point number out of an x87 FPU
34-
register and into a 64-bit memory location, rounding from extended
35-
precision to double precision in the process. On other platforms it does
36-
nothing. */
37-
38-
/* we take double rounding as evidence of x87 usage */
39-
#ifndef Py_LIMITED_API
40-
#ifndef Py_FORCE_DOUBLE
41-
# ifdef X87_DOUBLE_ROUNDING
42-
PyAPI_FUNC(double) _Py_force_double(double);
43-
# define Py_FORCE_DOUBLE(X) (_Py_force_double(X))
44-
# else
45-
# define Py_FORCE_DOUBLE(X) (X)
46-
# endif
47-
#endif
48-
#endif
49-
50-
/* Py_IS_NAN(X)
51-
* Return 1 if float or double arg is a NaN, else 0.
52-
* Caution:
53-
* X is evaluated more than once.
54-
* This may not work on all platforms. Each platform has *some*
55-
* way to spell this, though -- override in pyconfig.h if you have
56-
* a platform where it doesn't work.
57-
* Note: PC/pyconfig.h defines Py_IS_NAN as _isnan
58-
*/
59-
#ifndef Py_IS_NAN
60-
# if defined HAVE_DECL_ISNAN && HAVE_DECL_ISNAN == 1
61-
# define Py_IS_NAN(X) isnan(X)
62-
# else
63-
# define Py_IS_NAN(X) ((X) != (X))
64-
# endif
65-
#endif
66-
67-
/* Py_IS_INFINITY(X)
68-
* Return 1 if float or double arg is an infinity, else 0.
69-
* Caution:
70-
* X is evaluated more than once.
71-
* This implementation may set the underflow flag if |X| is very small;
72-
* it really can't be implemented correctly (& easily) before C99.
73-
* Override in pyconfig.h if you have a better spelling on your platform.
74-
* Py_FORCE_DOUBLE is used to avoid getting false negatives from a
75-
* non-infinite value v sitting in an 80-bit x87 register such that
76-
* v becomes infinite when spilled from the register to 64-bit memory.
77-
* Note: PC/pyconfig.h defines Py_IS_INFINITY as _isinf
78-
*/
79-
#ifndef Py_IS_INFINITY
80-
# if defined HAVE_DECL_ISINF && HAVE_DECL_ISINF == 1
81-
# define Py_IS_INFINITY(X) isinf(X)
82-
# else
83-
# define Py_IS_INFINITY(X) ((X) && \
84-
(Py_FORCE_DOUBLE(X)*0.5 == Py_FORCE_DOUBLE(X)))
85-
# endif
86-
#endif
34+
// Py_IS_INFINITY(X)
35+
// Return 1 if float or double arg is an infinity, else 0.
36+
#define Py_IS_INFINITY(X) isinf(X)
8737

88-
/* Py_IS_FINITE(X)
89-
* Return 1 if float or double arg is neither infinite nor NAN, else 0.
90-
* Some compilers (e.g. VisualStudio) have intrinsics for this, so a special
91-
* macro for this particular test is useful
92-
* Note: PC/pyconfig.h defines Py_IS_FINITE as _finite
93-
*/
94-
#ifndef Py_IS_FINITE
95-
# if defined HAVE_DECL_ISFINITE && HAVE_DECL_ISFINITE == 1
96-
# define Py_IS_FINITE(X) isfinite(X)
97-
# elif defined HAVE_FINITE
98-
# define Py_IS_FINITE(X) finite(X)
99-
# else
100-
# define Py_IS_FINITE(X) (!Py_IS_INFINITY(X) && !Py_IS_NAN(X))
101-
# endif
102-
#endif
38+
// Py_IS_FINITE(X)
39+
// Return 1 if float or double arg is neither infinite nor NAN, else 0.
40+
#define Py_IS_FINITE(X) isfinite(X)
10341

10442
/* HUGE_VAL is supposed to expand to a positive double infinity. Python
10543
* uses Py_HUGE_VAL instead because some platforms are broken in this
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Building Python now requires a C99 ``<math.h>`` header file providing
2+
``isinf()``, ``isnan()`` and ``isfinite()`` functions. Patch by Victor Stinner.
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Remove the ``Py_FORCE_DOUBLE()`` macro. It was used by the ``Py_IS_INFINITY()``
2+
macro. Patch by Victor Stinner.

PC/pyconfig.h

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -189,11 +189,6 @@ typedef _W64 int Py_ssize_t;
189189

190190
typedef int pid_t;
191191

192-
#include <float.h>
193-
#define Py_IS_NAN _isnan
194-
#define Py_IS_INFINITY(X) (!_finite(X) && !_isnan(X))
195-
#define Py_IS_FINITE(X) _finite(X)
196-
197192
/* define some ANSI types that are not defined in earlier Win headers */
198193
#if _MSC_VER >= 1200
199194
/* 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 */
358353

359354
/* Define to 1 if you have the `round' function. */
360355
#if _MSC_VER >= 1800
361-
#define HAVE_ROUND 1
356+
# define HAVE_ROUND 1
362357
#endif
363358

364-
/* Define to 1 if you have the `isinf' macro. */
365-
#define HAVE_DECL_ISINF 1
366-
367-
/* Define to 1 if you have the `isnan' function. */
368-
#define HAVE_DECL_ISNAN 1
369-
370359
/* Define if on AIX 3.
371360
System headers sometimes define this.
372361
We just want to avoid a redefinition error message. */

Python/pymath.c

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,5 @@
11
#include "Python.h"
22

3-
#ifdef X87_DOUBLE_ROUNDING
4-
/* On x86 platforms using an x87 FPU, this function is called from the
5-
Py_FORCE_DOUBLE macro (defined in pymath.h) to force a floating-point
6-
number out of an 80-bit x87 FPU register and into a 64-bit memory location,
7-
thus rounding from extended precision to double precision. */
8-
double _Py_force_double(double x)
9-
{
10-
volatile double y;
11-
y = x;
12-
return y;
13-
}
14-
#endif
15-
163

174
#ifdef HAVE_GCC_ASM_FOR_X87
185
// Inline assembly for getting and setting the 387 FPU control word on

configure

Lines changed: 0 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -15090,40 +15090,6 @@ _ACEOF
1509015090
fi
1509115091
done
1509215092

15093-
ac_fn_c_check_decl "$LINENO" "isinf" "ac_cv_have_decl_isinf" "#include <math.h>
15094-
"
15095-
if test "x$ac_cv_have_decl_isinf" = xyes; then :
15096-
ac_have_decl=1
15097-
else
15098-
ac_have_decl=0
15099-
fi
15100-
15101-
cat >>confdefs.h <<_ACEOF
15102-
#define HAVE_DECL_ISINF $ac_have_decl
15103-
_ACEOF
15104-
ac_fn_c_check_decl "$LINENO" "isnan" "ac_cv_have_decl_isnan" "#include <math.h>
15105-
"
15106-
if test "x$ac_cv_have_decl_isnan" = xyes; then :
15107-
ac_have_decl=1
15108-
else
15109-
ac_have_decl=0
15110-
fi
15111-
15112-
cat >>confdefs.h <<_ACEOF
15113-
#define HAVE_DECL_ISNAN $ac_have_decl
15114-
_ACEOF
15115-
ac_fn_c_check_decl "$LINENO" "isfinite" "ac_cv_have_decl_isfinite" "#include <math.h>
15116-
"
15117-
if test "x$ac_cv_have_decl_isfinite" = xyes; then :
15118-
ac_have_decl=1
15119-
else
15120-
ac_have_decl=0
15121-
fi
15122-
15123-
cat >>confdefs.h <<_ACEOF
15124-
#define HAVE_DECL_ISFINITE $ac_have_decl
15125-
_ACEOF
15126-
1512715093

1512815094
# For multiprocessing module, check that sem_open
1512915095
# actually works. For FreeBSD versions <= 7.2,

configure.ac

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4677,7 +4677,6 @@ LIBS="$LIBS $LIBM"
46774677

46784678
AC_CHECK_FUNCS([acosh asinh atanh copysign erf erfc expm1 finite gamma])
46794679
AC_CHECK_FUNCS([hypot lgamma log1p log2 round tgamma])
4680-
AC_CHECK_DECLS([isinf, isnan, isfinite], [], [], [[#include <math.h>]])
46814680

46824681
# For multiprocessing module, check that sem_open
46834682
# actually works. For FreeBSD versions <= 7.2,

pyconfig.h.in

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -214,18 +214,6 @@
214214
/* Define if you have the 'wchgat' function. */
215215
#undef HAVE_CURSES_WCHGAT
216216

217-
/* Define to 1 if you have the declaration of `isfinite', and to 0 if you
218-
don't. */
219-
#undef HAVE_DECL_ISFINITE
220-
221-
/* Define to 1 if you have the declaration of `isinf', and to 0 if you don't.
222-
*/
223-
#undef HAVE_DECL_ISINF
224-
225-
/* Define to 1 if you have the declaration of `isnan', and to 0 if you don't.
226-
*/
227-
#undef HAVE_DECL_ISNAN
228-
229217
/* Define to 1 if you have the declaration of `RTLD_DEEPBIND', and to 0 if you
230218
don't. */
231219
#undef HAVE_DECL_RTLD_DEEPBIND

0 commit comments

Comments
 (0)