Thanks to visit codestin.com
Credit goes to github.com

Skip to content

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

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 13, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions Doc/whatsnew/3.11.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
=============

Expand Down Expand Up @@ -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`.)
3 changes: 3 additions & 0 deletions Include/internal/pycore_pymath.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
80 changes: 9 additions & 71 deletions Include/pymath.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*/
Expand All @@ -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
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Building Python now requires a C99 ``<math.h>`` header file providing
``isinf()``, ``isnan()`` and ``isfinite()`` functions. Patch by Victor Stinner.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Remove the ``Py_FORCE_DOUBLE()`` macro. It was used by the ``Py_IS_INFINITY()``
macro. Patch by Victor Stinner.
13 changes: 1 addition & 12 deletions PC/pyconfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down Expand Up @@ -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. */
Expand Down
13 changes: 0 additions & 13 deletions Python/pymath.c
Original file line number Diff line number Diff line change
@@ -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
Expand Down
34 changes: 0 additions & 34 deletions configure
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
1 change: 0 additions & 1 deletion configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
12 changes: 0 additions & 12 deletions pyconfig.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down