mirror of
https://github.com/python/cpython.git
synced 2025-09-26 18:29:57 +00:00
Patch #871657: Set EDOM for `nan' return values on FreeBSD and OpenBSD.
This fixes a problem that math.sqrt(-1) doesn't raise math.error.
This commit is contained in:
parent
39a0f04421
commit
77d9a3effa
2 changed files with 25 additions and 12 deletions
|
@ -273,21 +273,34 @@ extern "C" {
|
||||||
(X) == -Py_HUGE_VAL))
|
(X) == -Py_HUGE_VAL))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Py_SET_ERANGE_ON_OVERFLOW(x)
|
/* Py_SET_ERRNO_ON_MATH_ERROR(x)
|
||||||
* If a libm function did not set errno, but it looks like the result
|
* If a libm function did not set errno, but it looks like the result
|
||||||
* overflowed, set errno to ERANGE. Set errno to 0 before calling a libm
|
* overflowed or not-a-number, set errno to ERANGE or EDOM. Set errno
|
||||||
* function, and invoke this macro after, passing the function result.
|
* to 0 before calling a libm function, and invoke this macro after,
|
||||||
|
* passing the function result.
|
||||||
* Caution:
|
* Caution:
|
||||||
* This isn't reliable. See Py_OVERFLOWED comments.
|
* This isn't reliable. See Py_OVERFLOWED comments.
|
||||||
* X is evaluated more than once.
|
* X is evaluated more than once.
|
||||||
*/
|
*/
|
||||||
#define Py_SET_ERANGE_IF_OVERFLOW(X) \
|
#if defined(__FreeBSD__) || defined(__OpenBSD__)
|
||||||
|
#define _Py_SET_EDOM_FOR_NAN(X) if (isnan(X)) errno = EDOM;
|
||||||
|
#else
|
||||||
|
#define _Py_SET_EDOM_FOR_NAN(X) ;
|
||||||
|
#endif
|
||||||
|
#define Py_SET_ERRNO_ON_MATH_ERROR(X) \
|
||||||
do { \
|
do { \
|
||||||
if (errno == 0 && ((X) == Py_HUGE_VAL || \
|
if (errno == 0) { \
|
||||||
(X) == -Py_HUGE_VAL)) \
|
if ((X) == Py_HUGE_VAL || (X) == -Py_HUGE_VAL) \
|
||||||
errno = ERANGE; \
|
errno = ERANGE; \
|
||||||
|
else _Py_SET_EDOM_FOR_NAN(X) \
|
||||||
|
} \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
|
/* Py_SET_ERANGE_ON_OVERFLOW(x)
|
||||||
|
* An alias of Py_SET_ERRNO_ON_MATH_ERROR for backward-compatibility.
|
||||||
|
*/
|
||||||
|
#define Py_SET_ERANGE_IF_OVERFLOW(X) Py_SET_ERRNO_ON_MATH_ERROR(X)
|
||||||
|
|
||||||
/* Py_ADJUST_ERANGE1(x)
|
/* Py_ADJUST_ERANGE1(x)
|
||||||
* Py_ADJUST_ERANGE2(x, y)
|
* Py_ADJUST_ERANGE2(x, y)
|
||||||
* Set errno to 0 before calling a libm function, and invoke one of these
|
* Set errno to 0 before calling a libm function, and invoke one of these
|
||||||
|
|
|
@ -57,7 +57,7 @@ math_1(PyObject *args, double (*func) (double), char *argsfmt)
|
||||||
PyFPE_START_PROTECT("in math_1", return 0)
|
PyFPE_START_PROTECT("in math_1", return 0)
|
||||||
x = (*func)(x);
|
x = (*func)(x);
|
||||||
PyFPE_END_PROTECT(x)
|
PyFPE_END_PROTECT(x)
|
||||||
Py_SET_ERANGE_IF_OVERFLOW(x);
|
Py_SET_ERRNO_ON_MATH_ERROR(x);
|
||||||
if (errno && is_error(x))
|
if (errno && is_error(x))
|
||||||
return NULL;
|
return NULL;
|
||||||
else
|
else
|
||||||
|
@ -74,7 +74,7 @@ math_2(PyObject *args, double (*func) (double, double), char *argsfmt)
|
||||||
PyFPE_START_PROTECT("in math_2", return 0)
|
PyFPE_START_PROTECT("in math_2", return 0)
|
||||||
x = (*func)(x, y);
|
x = (*func)(x, y);
|
||||||
PyFPE_END_PROTECT(x)
|
PyFPE_END_PROTECT(x)
|
||||||
Py_SET_ERANGE_IF_OVERFLOW(x);
|
Py_SET_ERRNO_ON_MATH_ERROR(x);
|
||||||
if (errno && is_error(x))
|
if (errno && is_error(x))
|
||||||
return NULL;
|
return NULL;
|
||||||
else
|
else
|
||||||
|
@ -143,7 +143,7 @@ math_frexp(PyObject *self, PyObject *args)
|
||||||
return NULL;
|
return NULL;
|
||||||
errno = 0;
|
errno = 0;
|
||||||
x = frexp(x, &i);
|
x = frexp(x, &i);
|
||||||
Py_SET_ERANGE_IF_OVERFLOW(x);
|
Py_SET_ERRNO_ON_MATH_ERROR(x);
|
||||||
if (errno && is_error(x))
|
if (errno && is_error(x))
|
||||||
return NULL;
|
return NULL;
|
||||||
else
|
else
|
||||||
|
@ -168,7 +168,7 @@ math_ldexp(PyObject *self, PyObject *args)
|
||||||
PyFPE_START_PROTECT("ldexp", return 0)
|
PyFPE_START_PROTECT("ldexp", return 0)
|
||||||
x = ldexp(x, exp);
|
x = ldexp(x, exp);
|
||||||
PyFPE_END_PROTECT(x)
|
PyFPE_END_PROTECT(x)
|
||||||
Py_SET_ERANGE_IF_OVERFLOW(x);
|
Py_SET_ERRNO_ON_MATH_ERROR(x);
|
||||||
if (errno && is_error(x))
|
if (errno && is_error(x))
|
||||||
return NULL;
|
return NULL;
|
||||||
else
|
else
|
||||||
|
@ -186,7 +186,7 @@ math_modf(PyObject *self, PyObject *args)
|
||||||
return NULL;
|
return NULL;
|
||||||
errno = 0;
|
errno = 0;
|
||||||
x = modf(x, &y);
|
x = modf(x, &y);
|
||||||
Py_SET_ERANGE_IF_OVERFLOW(x);
|
Py_SET_ERRNO_ON_MATH_ERROR(x);
|
||||||
if (errno && is_error(x))
|
if (errno && is_error(x))
|
||||||
return NULL;
|
return NULL;
|
||||||
else
|
else
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue