diff -r 19488e23dcdb Objects/longobject.c --- a/Objects/longobject.c Fri Jun 03 10:48:43 2016 +0300 +++ b/Objects/longobject.c Fri Jun 03 17:11:14 2016 +0300 @@ -71,7 +71,8 @@ #endif /* If a freshly-allocated int is already shared, it must - be a small integer, so negating it must go to PyLong_FromLong */ + be a small integer, so unless it is zero, negating it + must go to PyLong_FromLong */ Py_LOCAL_INLINE(void) _PyLong_Negate(PyLongObject **x_p) { @@ -83,6 +84,9 @@ return; } + if (Py_SIZE(x) == 0) + return; + *x_p = (PyLongObject *)PyLong_FromLong(-MEDIUM_VALUE(x)); Py_DECREF(x); } @@ -2975,6 +2979,9 @@ ; if (i < 0) return (PyLongObject *)PyLong_FromLong(0); + if (i == 0) + return (PyLongObject *)PyLong_FromLong((sdigit)a->ob_digit[0] - + (sdigit)b->ob_digit[0]); if (a->ob_digit[i] < b->ob_digit[i]) { sign = -1; { PyLongObject *temp = a; a = b; b = temp; } @@ -3004,7 +3011,7 @@ if (z == NULL) return NULL; } - return long_normalize(z); + return maybe_small_long(long_normalize(z)); } static PyObject * @@ -3055,7 +3062,9 @@ else z = x_add(a, b); if (z != NULL && Py_SIZE(z) != 0) - Py_SIZE(z) = -(Py_SIZE(z)); + _PyLong_Negate(&z); + if (z == NULL) + return NULL; } else { if (Py_SIZE(b) < 0)