From 76eb789ce091c0f815f756267809cc26b14be6b5 Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Sat, 24 Jan 2009 15:42:34 +0000 Subject: [PATCH] Merged revisions 68890 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r68890 | mark.dickinson | 2009-01-24 15:27:44 +0000 (Sat, 24 Jan 2009) | 6 lines Issue #4393: fix 3 classes of potential portability problems in longobject.c: - fix some places where counters into ob_digit were declared as int instead of Py_ssize_t - add (twodigit) casts where necessary - fix code in _PyLong_AsByteArray that uses << on negative values ........ --- Objects/longobject.c | 43 ++++++++++++++++++++----------------------- 1 file changed, 20 insertions(+), 23 deletions(-) diff --git a/Objects/longobject.c b/Objects/longobject.c index 65130696d40..4cf80c01384 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -513,7 +513,7 @@ _PyLong_FromByteArray(const unsigned char* bytes, size_t n, /* Because we're going LSB to MSB, thisbyte is more significant than what's already in accum, so needs to be prepended to accum. */ - accum |= thisbyte << accumbits; + accum |= (twodigits)thisbyte << accumbits; accumbits += 8; if (accumbits >= PyLong_SHIFT) { /* There's enough to fill a Python digit. */ @@ -542,7 +542,7 @@ _PyLong_AsByteArray(PyLongObject* v, unsigned char* bytes, size_t n, int little_endian, int is_signed) { - int i; /* index into v->ob_digit */ + Py_ssize_t i; /* index into v->ob_digit */ Py_ssize_t ndigits; /* |v->ob_size| */ twodigits accum; /* sliding register */ unsigned int accumbits; /* # bits in accum */ @@ -587,7 +587,7 @@ _PyLong_AsByteArray(PyLongObject* v, accumbits = 0; carry = do_twos_comp ? 1 : 0; for (i = 0; i < ndigits; ++i) { - twodigits thisdigit = v->ob_digit[i]; + digit thisdigit = v->ob_digit[i]; if (do_twos_comp) { thisdigit = (thisdigit ^ PyLong_MASK) + carry; carry = thisdigit >> PyLong_SHIFT; @@ -596,26 +596,23 @@ _PyLong_AsByteArray(PyLongObject* v, /* Because we're going LSB to MSB, thisdigit is more significant than what's already in accum, so needs to be prepended to accum. */ - accum |= thisdigit << accumbits; - accumbits += PyLong_SHIFT; + accum |= (twodigits)thisdigit << accumbits; /* The most-significant digit may be (probably is) at least partly empty. */ if (i == ndigits - 1) { /* Count # of sign bits -- they needn't be stored, * although for signed conversion we need later to - * make sure at least one sign bit gets stored. - * First shift conceptual sign bit to real sign bit. - */ - stwodigits s = (stwodigits)(thisdigit << - (8*sizeof(stwodigits) - PyLong_SHIFT)); - unsigned int nsignbits = 0; - while ((s < 0) == do_twos_comp && nsignbits < PyLong_SHIFT) { - ++nsignbits; - s <<= 1; + * make sure at least one sign bit gets stored. */ + digit s = do_twos_comp ? thisdigit ^ PyLong_MASK : + thisdigit; + while (s != 0) { + s >>= 1; + accumbits++; } - accumbits -= nsignbits; } + else + accumbits += PyLong_SHIFT; /* Store as many bytes as possible. */ while (accumbits >= 8) { @@ -1079,7 +1076,7 @@ convert_binop(PyObject *v, PyObject *w, PyLongObject **a, PyLongObject **b) { static digit v_iadd(digit *x, Py_ssize_t m, digit *y, Py_ssize_t n) { - int i; + Py_ssize_t i; digit carry = 0; assert(m >= n); @@ -1105,7 +1102,7 @@ v_iadd(digit *x, Py_ssize_t m, digit *y, Py_ssize_t n) static digit v_isub(digit *x, Py_ssize_t m, digit *y, Py_ssize_t n) { - int i; + Py_ssize_t i; digit borrow = 0; assert(m >= n); @@ -1171,7 +1168,7 @@ inplace_divrem1(digit *pout, digit *pin, Py_ssize_t size, digit n) digit hi; rem = (rem << PyLong_SHIFT) + *--pin; *--pout = hi = (digit)(rem / n); - rem -= hi * n; + rem -= (twodigits)hi * n; } return (digit)rem; } @@ -1436,11 +1433,11 @@ long_from_binary_base(char **str, int base) while (--p >= start) { int k = _PyLong_DigitValue[Py_CHARMASK(*p)]; assert(k >= 0 && k < base); - accum |= (twodigits)(k << bits_in_accum); + accum |= (twodigits)k << bits_in_accum; bits_in_accum += bits_per_char; if (bits_in_accum >= PyLong_SHIFT) { *pdigit++ = (digit)(accum & PyLong_MASK); - assert(pdigit - z->ob_digit <= (int)n); + assert(pdigit - z->ob_digit <= n); accum >>= PyLong_SHIFT; bits_in_accum -= PyLong_SHIFT; assert(bits_in_accum < PyLong_SHIFT); @@ -1449,7 +1446,7 @@ long_from_binary_base(char **str, int base) if (bits_in_accum) { assert(bits_in_accum <= PyLong_SHIFT); *pdigit++ = (digit)accum; - assert(pdigit - z->ob_digit <= (int)n); + assert(pdigit - z->ob_digit <= n); } while (pdigit - z->ob_digit < n) *pdigit++ = 0; @@ -1846,7 +1843,7 @@ x_divrem(PyLongObject *v1, PyLongObject *w1, PyLongObject **prem) digit vj = (j >= size_v) ? 0 : v->ob_digit[j]; twodigits q; stwodigits carry = 0; - int i; + Py_ssize_t i; SIGCHECK({ Py_DECREF(a); @@ -2008,7 +2005,7 @@ x_add(PyLongObject *a, PyLongObject *b) { Py_ssize_t size_a = ABS(Py_SIZE(a)), size_b = ABS(Py_SIZE(b)); PyLongObject *z; - int i; + Py_ssize_t i; digit carry = 0; /* Ensure a is the larger of the two: */