diff options
author | Edward Welbourne <edward.welbourne@qt.io> | 2019-09-05 17:50:17 +0200 |
---|---|---|
committer | Edward Welbourne <edward.welbourne@qt.io> | 2019-09-30 20:05:42 +0200 |
commit | 4bd6cd1992fdcdc933861ba646ea9da870670237 (patch) | |
tree | 55940f60c88352427f55f215d9970dbbbe97c174 /src | |
parent | 86876744f07cbaa01daca6869b896741878c39a3 (diff) |
Featurize support for signaling NaN
One of our compilers for emscripten coerces all signaling NaNs to
quiet ones, so won't do any actual signaling. Anyone relying on them
to do so shall be disappointed, so it's better that they know about it
at compile-time - or, at least, have the ability to find it out.
Put the signaling NaN producers (and remaining (test) code using them)
under the control of a feature that's disabled when numeric_limits
claims double has no signaling NaN. Assume the bootstrap library
doesn't need signaling NaNs. Sadly, until C++20 <bit>, there's no
contexpr way to test that alleged signalling and quiet NaNs are
actually distinct.
Added some auto-tests for signaling NaN, including that it's distinct
from quiet NaN. Any platform on which the last fails should disable
this feature.
Task-number: QTBUG-77967
Change-Id: I57e9d14bfe276732cd313887adc9acc354d88f08
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
Diffstat (limited to 'src')
-rw-r--r-- | src/corelib/global/qconfig-bootstrapped.h | 1 | ||||
-rw-r--r-- | src/corelib/global/qnumeric.cpp | 2 | ||||
-rw-r--r-- | src/corelib/global/qnumeric.h | 7 | ||||
-rw-r--r-- | src/corelib/global/qnumeric_p.h | 3 |
4 files changed, 10 insertions, 3 deletions
diff --git a/src/corelib/global/qconfig-bootstrapped.h b/src/corelib/global/qconfig-bootstrapped.h index 2e58dabf5f..e6ad80525a 100644 --- a/src/corelib/global/qconfig-bootstrapped.h +++ b/src/corelib/global/qconfig-bootstrapped.h @@ -109,6 +109,7 @@ # define QT_FEATURE_renameat2 -1 #endif #define QT_FEATURE_sharedmemory -1 +#define QT_FEATURE_signaling_nan -1 #define QT_FEATURE_slog2 -1 #ifdef __GLIBC_PREREQ # define QT_FEATURE_statx (__GLIBC_PREREQ(2, 28) ? 1 : -1) diff --git a/src/corelib/global/qnumeric.cpp b/src/corelib/global/qnumeric.cpp index 11440f40a4..9cb9c1283a 100644 --- a/src/corelib/global/qnumeric.cpp +++ b/src/corelib/global/qnumeric.cpp @@ -81,11 +81,13 @@ Q_CORE_EXPORT bool qIsNaN(float f) { return qt_is_nan(f); } */ Q_CORE_EXPORT bool qIsFinite(float f) { return qt_is_finite(f); } +#if QT_CONFIG(signaling_nan) /*! Returns the bit pattern of a signalling NaN as a double. \relates <QtGlobal> */ Q_CORE_EXPORT double qSNaN() { return qt_snan(); } +#endif /*! Returns the bit pattern of a quiet NaN as a double. diff --git a/src/corelib/global/qnumeric.h b/src/corelib/global/qnumeric.h index 6a0c64712f..2771eea64f 100644 --- a/src/corelib/global/qnumeric.h +++ b/src/corelib/global/qnumeric.h @@ -44,7 +44,6 @@ QT_BEGIN_NAMESPACE - Q_CORE_EXPORT Q_DECL_CONST_FUNCTION bool qIsInf(double d); Q_CORE_EXPORT Q_DECL_CONST_FUNCTION bool qIsNaN(double d); Q_CORE_EXPORT Q_DECL_CONST_FUNCTION bool qIsFinite(double d); @@ -53,7 +52,9 @@ Q_CORE_EXPORT Q_DECL_CONST_FUNCTION bool qIsInf(float f); Q_CORE_EXPORT Q_DECL_CONST_FUNCTION bool qIsNaN(float f); Q_CORE_EXPORT Q_DECL_CONST_FUNCTION bool qIsFinite(float f); Q_CORE_EXPORT Q_DECL_CONST_FUNCTION int qFpClassify(float val); +#if QT_CONFIG(signaling_nan) Q_CORE_EXPORT Q_DECL_CONST_FUNCTION double qSNaN(); +#endif Q_CORE_EXPORT Q_DECL_CONST_FUNCTION double qQNaN(); Q_CORE_EXPORT Q_DECL_CONST_FUNCTION double qInf(); @@ -61,7 +62,9 @@ Q_CORE_EXPORT quint32 qFloatDistance(float a, float b); Q_CORE_EXPORT quint64 qFloatDistance(double a, double b); #define Q_INFINITY (QT_PREPEND_NAMESPACE(qInf)()) -#define Q_SNAN (QT_PREPEND_NAMESPACE(qSNaN)()) +#if QT_CONFIG(signaling_nan) +# define Q_SNAN (QT_PREPEND_NAMESPACE(qSNaN)()) +#endif #define Q_QNAN (QT_PREPEND_NAMESPACE(qQNaN)()) QT_END_NAMESPACE diff --git a/src/corelib/global/qnumeric_p.h b/src/corelib/global/qnumeric_p.h index 21f9cfbef0..86e7997680 100644 --- a/src/corelib/global/qnumeric_p.h +++ b/src/corelib/global/qnumeric_p.h @@ -133,13 +133,14 @@ Q_DECL_CONSTEXPR Q_DECL_CONST_FUNCTION static inline double qt_inf() noexcept return std::numeric_limits<double>::infinity(); } -// Signaling NaN +#if QT_CONFIG(signaling_nan) Q_DECL_CONSTEXPR Q_DECL_CONST_FUNCTION static inline double qt_snan() noexcept { Q_STATIC_ASSERT_X(std::numeric_limits<double>::has_signaling_NaN, "platform has no definition for signaling NaN for type double"); return std::numeric_limits<double>::signaling_NaN(); } +#endif // Quiet NaN Q_DECL_CONSTEXPR Q_DECL_CONST_FUNCTION static inline double qt_qnan() noexcept |