diff options
author | Marc Mutz <marc.mutz@qt.io> | 2023-09-11 19:44:38 +0200 |
---|---|---|
committer | Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> | 2023-09-12 23:26:14 +0000 |
commit | e8fb761f758fe00f3f778e2b475ef3efbefff271 (patch) | |
tree | d553345c2ccc9df2e3b6079bfebb3413301deecb /src/corelib/global/qfloat16.h | |
parent | 4f450ddf1965a5d6220ba1460ae4514a4cad63b6 (diff) |
Fix qHash(qfloat16) to match Qt 6.4 behavior
There were two problems:
- On platforms where QFLOAT16_IS_NATIVE == true, a qHash(qfloat16{})
call has become ambiguous between the three FP qHash() overloads
(float, double, long double), where it was unambiguously calling the
float one in Qt 6.4. This SiC was caused by the replacement of
operator float() by operator __fp16() in
99c7f0419e66692260be56c0385badeacb3f6760, which is in Qt 6.5.
- On platforms where QFLOAT16_IS_NATIVE == false, qHash(qfloat16{})
would produce a different value from qHash(float{}), and therefore
Qt 6.4, when the seed was != 0, because the former would go via the
one-arg-to-two-arg qHash adapter while the latter one would
not. Since participating functions are inline, this causes old and
new code to produce different hash values for the same qfloat16,
leading to a BiC possibly corrupting QHash etc.
Fix both by adding an explicit qHash(qfloat16). This function is
inline, so it doesn't add a new symbol to 6.5.x.
[ChangeLog][QtCore] Fixed qHash(qfloat16) which was broken from 6.5.0
to 6.5.3, inclusive. If you compiled against one of the affected Qt
versions, you need to recompile against either Qt 6.4 or earlier or
6.5.4 or later, because the problematic code is inline.
Pick-to: 6.5
Fixes: QTBUG-116064
Fixes: QTBUG-116076
Change-Id: Id02bc29a6c3ec463352f4bef314c040369081e9b
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
(cherry picked from commit 6da6a17de9ccfcd5458ea72507b131660e0ab948)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
Diffstat (limited to 'src/corelib/global/qfloat16.h')
-rw-r--r-- | src/corelib/global/qfloat16.h | 5 |
1 files changed, 5 insertions, 0 deletions
diff --git a/src/corelib/global/qfloat16.h b/src/corelib/global/qfloat16.h index 76ea990c33..15dab5e713 100644 --- a/src/corelib/global/qfloat16.h +++ b/src/corelib/global/qfloat16.h @@ -6,8 +6,10 @@ #define QFLOAT16_H #include <QtCore/qglobal.h> +#include <QtCore/qhashfunctions.h> #include <QtCore/qmath.h> #include <QtCore/qnamespace.h> + #include <limits> #include <string.h> @@ -144,6 +146,9 @@ private: friend inline qfloat16 operator*(qfloat16 a, qfloat16 b) noexcept { return qfloat16(static_cast<NearestFloat>(a) * static_cast<NearestFloat>(b)); } friend inline qfloat16 operator/(qfloat16 a, qfloat16 b) noexcept { return qfloat16(static_cast<NearestFloat>(a) / static_cast<NearestFloat>(b)); } + friend size_t qHash(qfloat16 key, size_t seed = 0) noexcept + { return qHash(float(key), seed); } // 6.4 algorithm, so keep using it; ### Qt 7: fix QTBUG-116077 + #define QF16_MAKE_ARITH_OP_FP(FP, OP) \ friend inline FP operator OP(qfloat16 lhs, FP rhs) noexcept { return static_cast<FP>(lhs) OP rhs; } \ friend inline FP operator OP(FP lhs, qfloat16 rhs) noexcept { return lhs OP static_cast<FP>(rhs); } |