summaryrefslogtreecommitdiff
path: root/numpy
diff options
context:
space:
mode:
authorYu Feng <feyu@google.com>2020-07-13 11:02:21 -0700
committerGitHub <noreply@github.com>2020-07-13 19:02:21 +0100
commitb6bd0a6f02276a37c0bd4d5e838fb94ba3eef6fd (patch)
tree335628a590a5a7b162849dfb58a8e3cb18c16c15 /numpy
parentdd883ce53d0744c616de472215287d680c660ac5 (diff)
downloadnumpy-b6bd0a6f02276a37c0bd4d5e838fb94ba3eef6fd.tar.gz
MAINT: Avoid accessing uninitialized bytes getlimits (#16834)
This very simple flip of ordering avoids accessing the last 6 uninitialized bytes of 80-bit floats. Since none of our known `long double` patterns share the 10-byte prefix, this change does not effect behavior. Accessing these bytes does not invoke any undefined behavior, but it does cause false positives in tools like `msan` and `valgrind`, which is reason enough to avoid doing so. `msan` does not always report this error, likely due to the caching of memory allocation.
Diffstat (limited to 'numpy')
-rw-r--r--numpy/core/getlimits.py12
1 files changed, 8 insertions, 4 deletions
diff --git a/numpy/core/getlimits.py b/numpy/core/getlimits.py
index f73c21f67..fcb73e8ba 100644
--- a/numpy/core/getlimits.py
+++ b/numpy/core/getlimits.py
@@ -262,11 +262,15 @@ def _get_machar(ftype):
raise ValueError(repr(ftype))
# Detect known / suspected types
key = ftype('-0.1').newbyteorder('<').tobytes()
- ma_like = _KNOWN_TYPES.get(key)
- # Could be 80 bit == 10 byte extended precision, where last bytes can be
- # random garbage. Try comparing first 10 bytes to pattern.
- if ma_like is None and ftype == ntypes.longdouble:
+ ma_like = None
+ if ftype == ntypes.longdouble:
+ # Could be 80 bit == 10 byte extended precision, where last bytes can
+ # be random garbage.
+ # Comparing first 10 bytes to pattern first to avoid branching on the
+ # random garbage.
ma_like = _KNOWN_TYPES.get(key[:10])
+ if ma_like is None:
+ ma_like = _KNOWN_TYPES.get(key)
if ma_like is not None:
return ma_like
# Fall back to parameter discovery