From 3c9bb0daaf0cbff9135f88e55bae8243aa937faa Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 29 May 2024 14:31:17 -0300 Subject: [PATCH] tst_qfloat16: don't cause UB in converting from float to ints The test data is provided as float, so we must obey [conv.fpint]/1 when converting from float to integer types. There are values in the rows that are outside of the range of short and shorter integers, so just check the range. Fixes: QTBUG-125889 Pick-to: 6.7 Change-Id: If3345151ddf84c43a4f1fffd17d405ee0cd00d44 Reviewed-by: Ivan Solovev --- .../corelib/global/qfloat16/tst_qfloat16.cpp | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/tests/auto/corelib/global/qfloat16/tst_qfloat16.cpp b/tests/auto/corelib/global/qfloat16/tst_qfloat16.cpp index 7acf8c2cf6e..5f1ff673169 100644 --- a/tests/auto/corelib/global/qfloat16/tst_qfloat16.cpp +++ b/tests/auto/corelib/global/qfloat16/tst_qfloat16.cpp @@ -155,6 +155,7 @@ void tst_qfloat16::ordering_data() row(2.0f, -inf); row(-2.0f, nan); row(-inf, -2.0f); + // testing with values outside qfloat16 range row(0.0f, 13e5f); // generateRow(inf, 13e5f); // fails qfloat16 vs qfloat16 and qfloat16 vs int (QTBUG-118193) @@ -187,11 +188,21 @@ void tst_qfloat16::ordering() #undef CHECK_FP + auto check_int = [=](auto rhs) { + // check that we're in range before converting, otherwise + // [conv.fpint]/1 says it would be UB + using RHS = decltype(rhs); + if (right > double(std::numeric_limits::max())) + return; + if (auto min = std::numeric_limits::min(); min != 0 && right < double(min)) + return; + rhs = RHS(right); + const auto expectedRes = Qt::compareThreeWay(left, rhs); + QTestPrivate::testAllComparisonOperators(lhs, rhs, expectedRes); + }; #define CHECK_INT(RHS) \ do { \ - const auto rhs = static_cast(right); \ - const auto expectedRes = Qt::compareThreeWay(left, rhs); \ - QTestPrivate::testAllComparisonOperators(lhs, rhs, expectedRes); \ + check_int(static_cast(0)); \ POSTCHECK("qfloat16 vs " #RHS " comparison failed") \ } while (false) \ /* END */