Issue #18408: Rewrite NEGATE() macro in longobject.c to handle PyLong_FromLong() failure
This commit is contained in:
parent
5967bf4928
commit
8aed6f1c7d
|
@ -70,11 +70,21 @@ maybe_small_long(PyLongObject *v)
|
||||||
|
|
||||||
/* If a freshly-allocated long is already shared, it must
|
/* If a freshly-allocated long is already shared, it must
|
||||||
be a small integer, so negating it must go to PyLong_FromLong */
|
be a small integer, so negating it must go to PyLong_FromLong */
|
||||||
#define NEGATE(x) \
|
Py_LOCAL_INLINE(void)
|
||||||
do if (Py_REFCNT(x) == 1) Py_SIZE(x) = -Py_SIZE(x); \
|
_PyLong_Negate(PyLongObject **x_p)
|
||||||
else { PyObject* tmp=PyLong_FromLong(-MEDIUM_VALUE(x)); \
|
{
|
||||||
Py_DECREF(x); (x) = (PyLongObject*)tmp; } \
|
PyLongObject *x;
|
||||||
while(0)
|
|
||||||
|
x = (PyLongObject *)*x_p;
|
||||||
|
if (Py_REFCNT(x) == 1) {
|
||||||
|
Py_SIZE(x) = -Py_SIZE(x);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
*x_p = (PyLongObject *)PyLong_FromLong(-MEDIUM_VALUE(x));
|
||||||
|
Py_DECREF(x);
|
||||||
|
}
|
||||||
|
|
||||||
/* For long multiplication, use the O(N**2) school algorithm unless
|
/* For long multiplication, use the O(N**2) school algorithm unless
|
||||||
* both operands contain more than KARATSUBA_CUTOFF digits (this
|
* both operands contain more than KARATSUBA_CUTOFF digits (this
|
||||||
* being an internal Python long digit, in base BASE).
|
* being an internal Python long digit, in base BASE).
|
||||||
|
@ -2357,10 +2367,21 @@ long_divrem(PyLongObject *a, PyLongObject *b,
|
||||||
The quotient z has the sign of a*b;
|
The quotient z has the sign of a*b;
|
||||||
the remainder r has the sign of a,
|
the remainder r has the sign of a,
|
||||||
so a = b*z + r. */
|
so a = b*z + r. */
|
||||||
if ((Py_SIZE(a) < 0) != (Py_SIZE(b) < 0))
|
if ((Py_SIZE(a) < 0) != (Py_SIZE(b) < 0)) {
|
||||||
NEGATE(z);
|
_PyLong_Negate(&z);
|
||||||
if (Py_SIZE(a) < 0 && Py_SIZE(*prem) != 0)
|
if (z == NULL) {
|
||||||
NEGATE(*prem);
|
Py_CLEAR(*prem);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (Py_SIZE(a) < 0 && Py_SIZE(*prem) != 0) {
|
||||||
|
_PyLong_Negate(prem);
|
||||||
|
if (*prem == NULL) {
|
||||||
|
Py_DECREF(z);
|
||||||
|
Py_CLEAR(*prem);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
*pdiv = maybe_small_long(z);
|
*pdiv = maybe_small_long(z);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -2856,8 +2877,11 @@ x_sub(PyLongObject *a, PyLongObject *b)
|
||||||
borrow &= 1; /* Keep only one sign bit */
|
borrow &= 1; /* Keep only one sign bit */
|
||||||
}
|
}
|
||||||
assert(borrow == 0);
|
assert(borrow == 0);
|
||||||
if (sign < 0)
|
if (sign < 0) {
|
||||||
NEGATE(z);
|
_PyLong_Negate(&z);
|
||||||
|
if (z == NULL)
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
return long_normalize(z);
|
return long_normalize(z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3348,8 +3372,11 @@ long_mul(PyLongObject *a, PyLongObject *b)
|
||||||
|
|
||||||
z = k_mul(a, b);
|
z = k_mul(a, b);
|
||||||
/* Negate if exactly one of the inputs is negative. */
|
/* Negate if exactly one of the inputs is negative. */
|
||||||
if (((Py_SIZE(a) ^ Py_SIZE(b)) < 0) && z)
|
if (((Py_SIZE(a) ^ Py_SIZE(b)) < 0) && z) {
|
||||||
NEGATE(z);
|
_PyLong_Negate(&z);
|
||||||
|
if (z == NULL)
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
return (PyObject *)z;
|
return (PyObject *)z;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3796,7 +3823,9 @@ long_pow(PyObject *v, PyObject *w, PyObject *x)
|
||||||
Py_DECREF(c);
|
Py_DECREF(c);
|
||||||
c = temp;
|
c = temp;
|
||||||
temp = NULL;
|
temp = NULL;
|
||||||
NEGATE(c);
|
_PyLong_Negate(&c);
|
||||||
|
if (c == NULL)
|
||||||
|
goto Error;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if modulus == 1:
|
/* if modulus == 1:
|
||||||
|
@ -3896,10 +3925,7 @@ long_pow(PyObject *v, PyObject *w, PyObject *x)
|
||||||
goto Done;
|
goto Done;
|
||||||
|
|
||||||
Error:
|
Error:
|
||||||
if (z != NULL) {
|
Py_CLEAR(z);
|
||||||
Py_DECREF(z);
|
|
||||||
z = NULL;
|
|
||||||
}
|
|
||||||
/* fall through */
|
/* fall through */
|
||||||
Done:
|
Done:
|
||||||
if (Py_SIZE(b) > FIVEARY_CUTOFF) {
|
if (Py_SIZE(b) > FIVEARY_CUTOFF) {
|
||||||
|
@ -4029,10 +4055,10 @@ long_lshift(PyObject *v, PyObject *w)
|
||||||
|
|
||||||
shiftby = PyLong_AsSsize_t((PyObject *)b);
|
shiftby = PyLong_AsSsize_t((PyObject *)b);
|
||||||
if (shiftby == -1L && PyErr_Occurred())
|
if (shiftby == -1L && PyErr_Occurred())
|
||||||
goto lshift_error;
|
return NULL;
|
||||||
if (shiftby < 0) {
|
if (shiftby < 0) {
|
||||||
PyErr_SetString(PyExc_ValueError, "negative shift count");
|
PyErr_SetString(PyExc_ValueError, "negative shift count");
|
||||||
goto lshift_error;
|
return NULL;
|
||||||
}
|
}
|
||||||
/* wordshift, remshift = divmod(shiftby, PyLong_SHIFT) */
|
/* wordshift, remshift = divmod(shiftby, PyLong_SHIFT) */
|
||||||
wordshift = shiftby / PyLong_SHIFT;
|
wordshift = shiftby / PyLong_SHIFT;
|
||||||
|
@ -4044,9 +4070,11 @@ long_lshift(PyObject *v, PyObject *w)
|
||||||
++newsize;
|
++newsize;
|
||||||
z = _PyLong_New(newsize);
|
z = _PyLong_New(newsize);
|
||||||
if (z == NULL)
|
if (z == NULL)
|
||||||
goto lshift_error;
|
return NULL;
|
||||||
if (Py_SIZE(a) < 0)
|
if (Py_SIZE(a) < 0) {
|
||||||
NEGATE(z);
|
assert(Py_REFCNT(z) == 1);
|
||||||
|
Py_SIZE(z) = -Py_SIZE(z);
|
||||||
|
}
|
||||||
for (i = 0; i < wordshift; i++)
|
for (i = 0; i < wordshift; i++)
|
||||||
z->ob_digit[i] = 0;
|
z->ob_digit[i] = 0;
|
||||||
accum = 0;
|
accum = 0;
|
||||||
|
@ -4060,7 +4088,6 @@ long_lshift(PyObject *v, PyObject *w)
|
||||||
else
|
else
|
||||||
assert(!accum);
|
assert(!accum);
|
||||||
z = long_normalize(z);
|
z = long_normalize(z);
|
||||||
lshift_error:
|
|
||||||
return (PyObject *) maybe_small_long(z);
|
return (PyObject *) maybe_small_long(z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue