59 lines
2.4 KiB
Diff
59 lines
2.4 KiB
Diff
|
From e6df66d52152156ba8bcda64b37f4995bda72d2f Mon Sep 17 00:00:00 2001
|
||
|
From: Graham Markall <gmarkall@nvidia.com>
|
||
|
Date: Fri, 14 Jan 2022 21:24:40 +0000
|
||
|
Subject: [PATCH] Fix #7713: Ensure _prng_random_hash return has correct
|
||
|
bitwidth
|
||
|
|
||
|
When the hash width is 32 bits, get_next_int32 needs to be used because
|
||
|
that returns a 32-bit integer, as opposed to get_next_int, which returns
|
||
|
a 64-bit integer regardless of the supplied bitwidth.
|
||
|
|
||
|
This commit also alters the signature of _prng_random_hash to use
|
||
|
_Py_hash_t as the return type - it will be equal to types.intp, but the
|
||
|
intent should be clearer.
|
||
|
---
|
||
|
numba/cpython/hashing.py | 21 +++++++++++++++++----
|
||
|
1 file changed, 17 insertions(+), 4 deletions(-)
|
||
|
|
||
|
diff --git a/numba/cpython/hashing.py b/numba/cpython/hashing.py
|
||
|
index 5a8673b04b..227fc4e1c5 100644
|
||
|
--- a/numba/cpython/hashing.py
|
||
|
+++ b/numba/cpython/hashing.py
|
||
|
@@ -18,7 +18,8 @@
|
||
|
from numba.core import errors
|
||
|
from numba.core import types, utils
|
||
|
from numba.core.unsafe.bytes import grab_byte, grab_uint64_t
|
||
|
-from numba.cpython.randomimpl import get_state_ptr, get_next_int, const_int
|
||
|
+from numba.cpython.randomimpl import (const_int, get_next_int, get_next_int32,
|
||
|
+ get_state_ptr)
|
||
|
|
||
|
_py38_or_later = utils.PYVERSION >= (3, 8)
|
||
|
_py310_or_later = utils.PYVERSION >= (3, 10)
|
||
|
@@ -137,11 +138,23 @@ def _prng_random_hash(tyctx):
|
||
|
|
||
|
def impl(cgctx, builder, signature, args):
|
||
|
state_ptr = get_state_ptr(cgctx, builder, "internal")
|
||
|
- bits = const_int(types.intp.bitwidth)
|
||
|
- value = get_next_int(cgctx, builder, state_ptr, bits, False)
|
||
|
+ bits = const_int(_hash_width)
|
||
|
+
|
||
|
+ # Why not just use get_next_int() with the correct bitwidth?
|
||
|
+ # get_next_int() always returns an i64, because the bitwidth it is
|
||
|
+ # passed may not be a compile-time constant, so it needs to allocate
|
||
|
+ # the largest unit of storage that may be required. Therefore, if the
|
||
|
+ # hash width is 32, then we need to use get_next_int32() to ensure we
|
||
|
+ # don't return a wider-than-expected hash, even if everything above
|
||
|
+ # the low 32 bits would have been zero.
|
||
|
+ if _hash_width == 32:
|
||
|
+ value = get_next_int32(cgctx, builder, state_ptr)
|
||
|
+ else:
|
||
|
+ value = get_next_int(cgctx, builder, state_ptr, bits, False)
|
||
|
+
|
||
|
return value
|
||
|
|
||
|
- sig = types.intp()
|
||
|
+ sig = _Py_hash_t()
|
||
|
return sig, impl
|
||
|
|
||
|
|