summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--configure.json16
-rw-r--r--src/corelib/global/qconfig-bootstrapped.h1
-rw-r--r--src/corelib/global/qnumeric.cpp2
-rw-r--r--src/corelib/global/qnumeric.h7
-rw-r--r--src/corelib/global/qnumeric_p.h3
-rw-r--r--tests/auto/corelib/global/qnumeric/tst_qnumeric.cpp15
-rw-r--r--tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp2
-rw-r--r--tests/auto/gui/painting/qpainterpath/tst_qpainterpath.cpp4
8 files changed, 47 insertions, 3 deletions
diff --git a/configure.json b/configure.json
index 5ee27fec62..70ad9440c8 100644
--- a/configure.json
+++ b/configure.json
@@ -484,6 +484,17 @@
]
}
},
+ "signaling_nan": {
+ "label": "Signaling NaN for doubles",
+ "type": "compile",
+ "test": {
+ "head": [ "#include <limits>" ],
+ "main": [
+ "using B = std::numeric_limits<double>;",
+ "static_assert(B::has_signaling_NaN, \"System lacks signaling NaN\");"
+ ]
+ }
+ },
"sse2": {
"label": "SSE2 instructions",
"type": "x86Simd"
@@ -1005,6 +1016,11 @@
{ "type": "define", "name": "QT_REDUCE_RELOCATIONS" }
]
},
+ "signaling_nan": {
+ "label": "Signaling NaN",
+ "condition": "tests.signaling_nan",
+ "output": [ "publicFeature" ]
+ },
"sse2": {
"label": "SSE2",
"condition": "(arch.i386 || arch.x86_64) && tests.sse2",
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
diff --git a/tests/auto/corelib/global/qnumeric/tst_qnumeric.cpp b/tests/auto/corelib/global/qnumeric/tst_qnumeric.cpp
index 5697d21547..a6d600e125 100644
--- a/tests/auto/corelib/global/qnumeric/tst_qnumeric.cpp
+++ b/tests/auto/corelib/global/qnumeric/tst_qnumeric.cpp
@@ -44,6 +44,9 @@ private slots:
void fuzzyCompare();
void rawNaN_data();
void rawNaN();
+#if QT_CONFIG(signaling_nan)
+ void distinctNaN();
+#endif
void generalNaN_data();
void generalNaN();
void infinity();
@@ -139,6 +142,9 @@ void tst_QNumeric::rawNaN_data()
QTest::addColumn<double>("nan");
QTest::newRow("quiet") << qQNaN();
+#if QT_CONFIG(signaling_nan)
+ QTest::newRow("signaling") << qSNaN();
+#endif
}
void tst_QNumeric::rawNaN()
@@ -147,6 +153,15 @@ void tst_QNumeric::rawNaN()
checkNaN(nan);
}
+#if QT_CONFIG(signaling_nan)
+void tst_QNumeric::distinctNaN()
+{
+ const double qnan = qQNaN();
+ const double snan = qSNaN();
+ QVERIFY(memcmp(&qnan, &snan, sizeof(double)) != 0);
+}
+#endif
+
void tst_QNumeric::generalNaN_data()
{
QTest::addColumn<int>("most");
diff --git a/tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp b/tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp
index 6fa82ea681..c6733205e5 100644
--- a/tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp
+++ b/tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp
@@ -1413,10 +1413,12 @@ void tst_QCborValue::toCbor_data()
// The rest of these tests are conversions whose decoding does not yield
// back the same QCborValue.
+#if QT_CONFIG(signaling_nan)
// Signalling NaN get normalized to quiet ones
QTest::newRow("Double:snan") << QCborValue(qSNaN()) << raw("\xfb\x7f\xf8\0""\0\0\0\0\0") << QCborValue::EncodingOptions();
QTest::newRow("Float:snan") << QCborValue(qSNaN()) << raw("\xfa\x7f\xc0\0\0") << QCborValue::EncodingOptions(QCborValue::UseFloat);
QTest::newRow("Float16:snan") << QCborValue(qSNaN()) << raw("\xf9\x7e\0") << QCborValue::EncodingOptions(QCborValue::UseFloat16);
+#endif
// Floating point written as integers are read back as integers
QTest::newRow("UseInteger:0") << QCborValue(0.) << raw("\x00") << QCborValue::EncodingOptions(QCborValue::UseIntegers);
diff --git a/tests/auto/gui/painting/qpainterpath/tst_qpainterpath.cpp b/tests/auto/gui/painting/qpainterpath/tst_qpainterpath.cpp
index 67cf9a321a..86a8965cec 100644
--- a/tests/auto/gui/painting/qpainterpath/tst_qpainterpath.cpp
+++ b/tests/auto/gui/painting/qpainterpath/tst_qpainterpath.cpp
@@ -88,7 +88,9 @@ private slots:
void testToFillPolygons();
+#if QT_CONFIG(signaling_nan)
void testNaNandInfinites();
+#endif
void closing();
@@ -1228,6 +1230,7 @@ void tst_QPainterPath::testToFillPolygons()
QCOMPARE(polygons.first().count(QPointF(70, 50)), 0);
}
+#if QT_CONFIG(signaling_nan)
void tst_QPainterPath::testNaNandInfinites()
{
QPainterPath path1;
@@ -1271,6 +1274,7 @@ void tst_QPainterPath::testNaNandInfinites()
path1.lineTo(QPointF(1, 1));
QVERIFY(path1 != path2);
}
+#endif // signaling_nan
void tst_QPainterPath::connectPathDuplicatePoint()
{