Commit 297c8899 authored by Hye-Shik Chang's avatar Hye-Shik Chang

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.
parent 8e2f3808
...@@ -273,21 +273,34 @@ extern "C" { ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment