Commit 798ee0cd authored by Joseph Weston's avatar Joseph Weston
Browse files

correct signed -> unsigned temporaries in hash calculation

This bug only seems to materialize on Windows, but now the types match
https://github.com/python/cpython/blob/master/Objects/longobject.c#L3031
Also inline 'old_hash', now that it is used in a single place only.
parent 9953b984
...@@ -806,11 +806,6 @@ fail: ...@@ -806,11 +806,6 @@ fail:
// in Python. As tinyarrays compare equal to equivalent tuples it is important // in Python. As tinyarrays compare equal to equivalent tuples it is important
// for the hashes to agree. If not, there will be problems with dictionaries. // for the hashes to agree. If not, there will be problems with dictionaries.
long old_hash(long x)
{
return x != -1 ? x : -2;
}
#if PY_MAJOR_VERSION >= 3 #if PY_MAJOR_VERSION >= 3
// the only documentation for this is in the Python sourcecode // the only documentation for this is in the Python sourcecode
...@@ -857,7 +852,7 @@ const Py_hash_t HASH_IMAG = 1000003L; ...@@ -857,7 +852,7 @@ const Py_hash_t HASH_IMAG = 1000003L;
Py_hash_t hash(long x) Py_hash_t hash(long x)
{ {
return old_hash(x); return x != -1 ? x : -2;
} }
#endif #endif
...@@ -887,10 +882,10 @@ Py_hash_t hash(PyObject *obj) ...@@ -887,10 +882,10 @@ Py_hash_t hash(PyObject *obj)
T *p = self->data(); T *p = self->data();
if (ndim == 0) return hash(*p); if (ndim == 0) return hash(*p);
const long mult_init = 1000003, r_init = 0x345678; const Py_uhash_t mult_init = 1000003, r_init = 0x345678;
const long mul_addend = 82520, r_addend = 97531; const Py_uhash_t mul_addend = 82520, r_addend = 97531;
Py_ssize_t i[max_ndim]; Py_ssize_t i[max_ndim];
long mult[max_ndim], r[max_ndim]; Py_uhash_t mult[max_ndim], r[max_ndim];
--ndim; // For convenience. --ndim; // For convenience.
int d = 0; int d = 0;
i[0] = shape[0]; i[0] = shape[0];
...@@ -909,9 +904,14 @@ Py_hash_t hash(PyObject *obj) ...@@ -909,9 +904,14 @@ Py_hash_t hash(PyObject *obj)
r[d] = r_init; r[d] = r_init;
} }
} else { } else {
if (d == 0) return old_hash(r[0] + r_addend); if (d == 0) {
Py_uhash_t r_next = r[0] + r_addend;
return r_next == Py_uhash_t(-1) ? -2 : r_next;
}
--d; --d;
r[d] = (r[d] ^ old_hash(r[d+1] + r_addend)) * mult[d]; Py_uhash_t r_next = r[d+1] + r_addend;
r_next = r_next == Py_uhash_t(-1) ? -2 : r_next;
r[d] = (r[d] ^ r_next) * mult[d];
mult[d] += mul_addend + 2 * i[d]; mult[d] += mul_addend + 2 * i[d];
} }
} }
......
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