Details
-
Bug
-
Resolution: Fixed
-
Not Evaluated
-
6.7.0 Beta1, 6.7.0 Beta2, 6.7.0 Beta3, 6.7.0 RC, 6.7.0 RC2, 6.7.0, 6.7.1
-
None
-
VxWorks 7 24.03 on the BD-SL-i.MX6 board (32bit arm)
-
-
3c9bb0daa (dev), b927ef2ce (6.7)
Description
The test fails with the log:
FAIL! : tst_qfloat16::ordering(0.000000_vs_1300000.000000) The computed value is expected to be equal to the baseline, but is not Computed (lhs < rhs) : 0 Baseline (!expectedUnordered && expectedLess): 1 Loc: [/home/qt/work/install/target/include/QtTest/6.8.0/QtTest/private/qcomparisontesthelper_p.h(255)] QDEBUG : tst_qfloat16::ordering(0.000000_vs_1300000.000000) qfloat16 vs qint16 comparison failed FAIL! : tst_qfloat16::ordering(0.000000_vs_-1300000.000000) The computed value is expected to be equal to the baseline, but is not Computed (lhs < rhs) : 1 Baseline (!expectedUnordered && expectedLess): 0 Loc: [/home/qt/work/install/target/include/QtTest/6.8.0/QtTest/private/qcomparisontesthelper_p.h(255)] QDEBUG : tst_qfloat16::ordering(0.000000_vs_-1300000.000000) qfloat16 vs qint16 comparison failed
It fails on the VxWorks platform because it exercises Undefined Behaviour, which returns something different on this platform than on other platforms.
Analysis
While testing tst_qfloat16::ordering, there is a code that checks qfloat16 against various integer types:
CHECK_INT(int); CHECK_INT(qint8); CHECK_INT(signed char); CHECK_INT(qint16); CHECK_INT(qint32); CHECK_INT(qint64);
The macro expands to the following:
#define CHECK_INT(RHS) \ do { \ const auto rhs = static_cast<RHS>(right); \ const auto expectedRes = Qt::compareThreeWay(left, rhs); \ QTestPrivate::testAllComparisonOperators(lhs, rhs, expectedRes); \ POSTCHECK("qfloat16 vs " #RHS " comparison failed") \ } while (false) \ /* END */
The problematic line is the following:
const auto rhs = static_cast<RHS>(right);
Where the right variable has various floating values - one of the problematic values is
13e5f. The conversion is defined as truncating the fraction part, but the result is undefined if the resulting value cannot be represented in the destination type (see: https://eel.is/c++draft/conv#fpint-1).
On the VxWorks platform, the static_cast<qint16>(13e5f) returns 0, which leads to the failing tests. The return value is ok as it is an undefined behavior.
You can check it also here: https://godbolt.org/z/dqGzc1Ghn It returns different results on every run - in my case, it returns the following:
29024 13696 13696 1300000 1300000 1300000
Attachments
For Gerrit Dashboard: QTBUG-125889 | ||||||
---|---|---|---|---|---|---|
# | Subject | Branch | Project | Status | CR | V |
564457,3 | tst_qfloat16: don't cause UB in converting from float to ints | dev | qt/qtbase | Status: MERGED | +2 | 0 |
564662,2 | tst_qfloat16: don't cause UB in converting from float to ints | 6.7 | qt/qtbase | Status: MERGED | +2 | 0 |