diff options
Diffstat (limited to 'tests/auto/corelib/text')
18 files changed, 550 insertions, 48 deletions
diff --git a/tests/auto/corelib/text/qanystringview/tst_qanystringview.cpp b/tests/auto/corelib/text/qanystringview/tst_qanystringview.cpp index 0eaadb870c..398be96530 100644 --- a/tests/auto/corelib/text/qanystringview/tst_qanystringview.cpp +++ b/tests/auto/corelib/text/qanystringview/tst_qanystringview.cpp @@ -356,6 +356,29 @@ private Q_SLOTS: fromLiteral(u8"Hello, World!"); // char[] in <= C++17, char8_t[] in >= C++20 } + void fromChar() const { fromCharacter('\xE4', 1); } + void fromUChar() const { fromCharacter(static_cast<unsigned char>('\xE4'), 1); } + void fromSChar() const { fromCharacter(static_cast<signed char>('\xE4'), 1); } + void fromChar16T() const { fromCharacter(u'ä', 1); } + void fromUShort() const { fromCharacter(ushort(0xE4), 1); } + void fromChar32T() const { + fromCharacter(U'ä', 1); + if (QTest::currentTestFailed()) + return; + fromCharacter(U'\x1F0A0', 2); // U+1F0A0: PLAYING CARD BACK + } + void fromWCharT() const { + ONLY_WIN(fromCharacter(L'ä', 1)); // should work on Unix, too (char32_t does) + } + void fromQChar() const { fromCharacter(QChar(u'ä'), 1); } + void fromQLatin1Char() const { fromCharacter(QLatin1Char('\xE4'), 1); } + void fromQCharSpecialCharacter() const { + fromCharacter(QChar::ReplacementCharacter, 1); + if (QTest::currentTestFailed()) + return; + fromCharacter(QChar::LastValidCodePoint, 1); + } + void fromChar16TStar() const { fromLiteral(u"Hello, World!"); } void fromWCharTStar() const { ONLY_WIN(fromLiteral(L"Hello, World!")); } @@ -393,6 +416,8 @@ private: template <typename Char> void fromLiteral(const Char *arg) const; template <typename Char> + void fromCharacter(Char arg, qsizetype expectedSize) const; + template <typename Char> void fromRange() const; template <typename Char, typename Container> void fromContainer() const; @@ -673,6 +698,44 @@ void tst_QAnyStringView::fromLiteral(const Char *arg) const conversion_tests(arg); } +template<typename Char> +void tst_QAnyStringView::fromCharacter(Char arg, qsizetype expectedSize) const +{ + // Need to re-create a new QASV(arg) each time, QASV(Char).data() dangles + // after the end of the Full Expression: + + static_assert(noexcept(QAnyStringView(arg)), + "If this fails, we may be creating a temporary QString/QByteArray"); + + QCOMPARE(QAnyStringView(arg).size(), expectedSize); + + // QCOMPARE(QAnyStringView(arg), arg); // not all pairs compile, so do it manually: + + // Check implicit conversion: + const QChar chars[] = { + [](QAnyStringView v) { return v.front(); }(arg), + [](QAnyStringView v) { return v.back(); }(arg), + }; + + switch (expectedSize) { + case 1: + if constexpr (std::is_same_v<Char, signed char>) // QChar doesn't have a ctor for this + QCOMPARE(chars[0], QChar(uchar(arg))); + else + QCOMPARE(chars[0], QChar(arg)); + break; + case 2: + QCOMPARE_EQ(QAnyStringView(arg), QStringView::fromArray(chars)); + if constexpr (std::is_convertible_v<Char, char32_t>) + QCOMPARE_EQ(QAnyStringView(arg), QStringView(QChar::fromUcs4(arg))); + break; + default: + QFAIL("Don't know how to compare this type to QAnyStringView"); + } + + // conversion_tests() would produce dangling references +} + template <typename Char> void tst_QAnyStringView::fromRange() const { diff --git a/tests/auto/corelib/text/qbytearrayview/CMakeLists.txt b/tests/auto/corelib/text/qbytearrayview/CMakeLists.txt index c78a81c7bd..8922ae2267 100644 --- a/tests/auto/corelib/text/qbytearrayview/CMakeLists.txt +++ b/tests/auto/corelib/text/qbytearrayview/CMakeLists.txt @@ -15,3 +15,10 @@ qt_internal_add_test(tst_qbytearrayview SOURCES tst_qbytearrayview.cpp ) + +if(QT_FEATURE_sanitize_undefined) + qt_internal_extend_target(tst_qbytearrayview + DEFINES + QT_SANITIZE_UNDEFINED # GCC (in)famously doesn't provide a predefined macro for this + ) +endif() diff --git a/tests/auto/corelib/text/qbytearrayview/tst_qbytearrayview.cpp b/tests/auto/corelib/text/qbytearrayview/tst_qbytearrayview.cpp index 894f0430dd..702e1840da 100644 --- a/tests/auto/corelib/text/qbytearrayview/tst_qbytearrayview.cpp +++ b/tests/auto/corelib/text/qbytearrayview/tst_qbytearrayview.cpp @@ -262,10 +262,9 @@ void tst_QByteArrayView::constExpr() const static_assert(!bv2.empty()); static_assert(bv2.size() == 5); } -#if !defined(Q_CC_GNU) || defined(Q_CC_CLANG) +#if !defined(Q_CC_GNU_ONLY) || !defined(QT_SANITIZE_UNDEFINED) // Below checks are disabled because of a compilation issue with GCC and // -fsanitize=undefined. See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71962. - // Note: Q_CC_GNU is also defined for Clang, so we need to check that too. { static constexpr char hello[] = "Hello"; constexpr QByteArrayView bv(hello); @@ -307,6 +306,9 @@ void tst_QByteArrayView::constExpr() const static_assert(bv.back() == 'o'); static_assert(bv.last() == 'o'); + constexpr auto bv2 = QByteArrayView::fromArray(hello); + QCOMPARE_EQ(bv, bv2); + constexpr std::string_view sv = bv; static_assert(bv.size() == sv.size()); #ifdef AMBIGUOUS_CALL // QTBUG-108805 @@ -416,7 +418,7 @@ void tst_QByteArrayView::fromArray() const { static constexpr char hello[] = "Hello\0abc\0\0."; - constexpr QByteArrayView bv = QByteArrayView::fromArray(hello); + const QByteArrayView bv = QByteArrayView::fromArray(hello); QCOMPARE(bv.size(), 13); QVERIFY(!bv.empty()); QVERIFY(!bv.isEmpty()); diff --git a/tests/auto/corelib/text/qlatin1stringmatcher/tst_qlatin1stringmatcher.cpp b/tests/auto/corelib/text/qlatin1stringmatcher/tst_qlatin1stringmatcher.cpp index 82e12bdfca..ba098fd23c 100644 --- a/tests/auto/corelib/text/qlatin1stringmatcher/tst_qlatin1stringmatcher.cpp +++ b/tests/auto/corelib/text/qlatin1stringmatcher/tst_qlatin1stringmatcher.cpp @@ -25,6 +25,7 @@ class tst_QLatin1StringMatcher : public QObject private slots: void overloads(); void staticOverloads(); + void staticOverloads_QStringViewHaystack(); void interface(); void indexIn(); void haystacksWithMoreThan4GiBWork(); @@ -44,6 +45,12 @@ void tst_QLatin1StringMatcher::overloads() QCOMPARE(m.indexIn("Hellohello"_L1), 5); QCOMPARE(m.indexIn("helloHello"_L1), 0); QCOMPARE(m.indexIn("helloHello"_L1, 1), -1); + + QCOMPARE(m.indexIn(u"hello"), 0); + QCOMPARE(m.indexIn(u"Hello"), -1); + QCOMPARE(m.indexIn(u"Hellohello"), 5); + QCOMPARE(m.indexIn(u"helloHello"), 0); + QCOMPARE(m.indexIn(u"helloHello", 1), -1); } { QLatin1StringMatcher m("Hello"_L1, Qt::CaseSensitive); @@ -53,6 +60,12 @@ void tst_QLatin1StringMatcher::overloads() QCOMPARE(m.indexIn("Hellohello"_L1), 0); QCOMPARE(m.indexIn("helloHello"_L1), 5); QCOMPARE(m.indexIn("helloHello"_L1, 6), -1); + + QCOMPARE(m.indexIn(u"hello"), -1); + QCOMPARE(m.indexIn(u"Hello"), 0); + QCOMPARE(m.indexIn(u"Hellohello"), 0); + QCOMPARE(m.indexIn(u"helloHello"), 5); + QCOMPARE(m.indexIn(u"helloHello", 6), -1); } { QLatin1StringMatcher m("hello"_L1, Qt::CaseInsensitive); @@ -63,6 +76,13 @@ void tst_QLatin1StringMatcher::overloads() QCOMPARE(m.indexIn("helloHello"_L1), 0); QCOMPARE(m.indexIn("helloHello"_L1, 1), 5); QCOMPARE(m.indexIn("helloHello"_L1, 6), -1); + + QCOMPARE(m.indexIn(u"hello"), 0); + QCOMPARE(m.indexIn(u"Hello"), 0); + QCOMPARE(m.indexIn(u"Hellohello"), 0); + QCOMPARE(m.indexIn(u"helloHello"), 0); + QCOMPARE(m.indexIn(u"helloHello", 1), 5); + QCOMPARE(m.indexIn(u"helloHello", 6), -1); } { QLatin1StringMatcher m("Hello"_L1, Qt::CaseInsensitive); @@ -73,6 +93,13 @@ void tst_QLatin1StringMatcher::overloads() QCOMPARE(m.indexIn("helloHello"_L1), 0); QCOMPARE(m.indexIn("helloHello"_L1, 1), 5); QCOMPARE(m.indexIn("helloHello"_L1, 6), -1); + + QCOMPARE(m.indexIn(u"hello"), 0); + QCOMPARE(m.indexIn(u"Hello"), 0); + QCOMPARE(m.indexIn(u"Hellohello"), 0); + QCOMPARE(m.indexIn(u"helloHello"), 0); + QCOMPARE(m.indexIn(u"helloHello", 1), 5); + QCOMPARE(m.indexIn(u"helloHello", 6), -1); } { QLatin1StringMatcher m(hello, Qt::CaseSensitive); @@ -81,6 +108,11 @@ void tst_QLatin1StringMatcher::overloads() QCOMPARE(m.indexIn(hello, 1), -1); QCOMPARE(m.indexIn(hello2, 1), hello.size()); QCOMPARE(m.indexIn(hello2, 6), -1); + + QCOMPARE(m.indexIn(QString::fromLatin1(hello)), 0); + QCOMPARE(m.indexIn(QString::fromLatin1(hello), 1), -1); + QCOMPARE(m.indexIn(QString::fromLatin1(hello2), 1), hello.size()); + QCOMPARE(m.indexIn(QString::fromLatin1(hello2), 6), -1); } } @@ -206,6 +238,129 @@ void tst_QLatin1StringMatcher::staticOverloads() #endif } +void tst_QLatin1StringMatcher::staticOverloads_QStringViewHaystack() +{ +#ifdef QT_STATIC_BOYER_MOORE_NOT_SUPPORTED + QSKIP("Test is only valid on an OS that supports static latin1 string matcher"); +#else + constexpr QStringView hello = u"hello"; + QString hello2B = QStringView(hello).toString().repeated(2); + hello2B += QStringView(u"🍉"); + QStringView hello2(hello2B); + { + static constexpr auto m = qMakeStaticCaseSensitiveLatin1StringMatcher("hel"); + QCOMPARE(m.indexIn(QStringView(u"hello🍉")), 0); + QCOMPARE(m.indexIn(QStringView(u"Hello🍉")), -1); + QCOMPARE(m.indexIn(QStringView(u"Hellohello🍉")), 5); + QCOMPARE(m.indexIn(QStringView(u"helloHello🍉")), 0); + QCOMPARE(m.indexIn(QStringView(u"he🍉")), -1); + QCOMPARE(m.indexIn(QStringView(u"hel🍉")), 0); + QCOMPARE(m.indexIn(hello), 0); + QCOMPARE(m.indexIn(hello, 1), -1); // from is 1 + QCOMPARE(m.indexIn(hello2, 2), hello.size()); // from is 2 + QCOMPARE(m.indexIn(hello2, 3), hello.size()); // from is 3 + QCOMPARE(m.indexIn(hello2, 6), -1); // from is 6 + static_assert(m.indexIn(QStringView(u"hello🍉")) == 0); + static_assert(m.indexIn(QStringView(u"Hello🍉")) == -1); + static_assert(m.indexIn(QStringView(u"Hellohello🍉")) == 5); + static_assert(m.indexIn(QStringView(u"helloHello🍉")) == 0); + static_assert(m.indexIn(QStringView(u"he🍉")) == -1); + static_assert(m.indexIn(QStringView(u"hel🍉")) == 0); + static_assert(m.indexIn(QStringView(u"hellohello🍉"), 2) == 5); // from is 2 + static_assert(m.indexIn(QStringView(u"hellohello🍉"), 3) == 5); // from is 3 + static_assert(m.indexIn(QStringView(u"hellohello🍉"), 6) == -1); // from is 6 + } + { + static constexpr auto m = qMakeStaticCaseSensitiveLatin1StringMatcher("Hel"); + QCOMPARE(m.indexIn(QStringView(u"hello🍉")), -1); + QCOMPARE(m.indexIn(QStringView(u"Hello🍉")), 0); + QCOMPARE(m.indexIn(QStringView(u"Hellohello🍉")), 0); + QCOMPARE(m.indexIn(QStringView(u"helloHello🍉")), 5); + QCOMPARE(m.indexIn(QStringView(u"helloHello🍉"), 6), -1); + QCOMPARE(m.indexIn(QStringView(u"He🍉")), -1); + QCOMPARE(m.indexIn(QStringView(u"Hel🍉")), 0); + QCOMPARE(m.indexIn(hello), -1); + QCOMPARE(m.indexIn(hello2, 2), -1); // from is 2 + QCOMPARE(m.indexIn(hello2, 6), -1); // from is 6 + static_assert(m.indexIn(QStringView(u"hello🍉")) == -1); + static_assert(m.indexIn(QStringView(u"Hello🍉")) == 0); + static_assert(m.indexIn(QStringView(u"Hellohello🍉")) == 0); + static_assert(m.indexIn(QStringView(u"helloHello🍉")) == 5); + static_assert(m.indexIn(QStringView(u"helloHello🍉"), 6) == -1); + static_assert(m.indexIn(QStringView(u"He🍉")) == -1); + static_assert(m.indexIn(QStringView(u"Hel🍉")) == 0); + static_assert(m.indexIn(QStringView(u"hellohello🍉"), 2) == -1); // from is 2 + static_assert(m.indexIn(QStringView(u"hellohello🍉"), 6) == -1); // from is 6 + } + { + static constexpr auto m = qMakeStaticCaseInsensitiveLatin1StringMatcher("hel"); + QCOMPARE(m.indexIn(QStringView(u"hello🍉")), 0); + QCOMPARE(m.indexIn(QStringView(u"Hello🍉")), 0); + QCOMPARE(m.indexIn(QStringView(u"Hellohello🍉")), 0); + QCOMPARE(m.indexIn(QStringView(u"helloHello🍉")), 0); + QCOMPARE(m.indexIn(QStringView(u"he🍉")), -1); + QCOMPARE(m.indexIn(QStringView(u"hel🍉")), 0); + QCOMPARE(m.indexIn(hello), 0); + QCOMPARE(m.indexIn(hello, 1), -1); + QCOMPARE(m.indexIn(hello2, 2), hello.size()); // from is 2 + QCOMPARE(m.indexIn(hello2, 3), hello.size()); // from is 3 + QCOMPARE(m.indexIn(hello2, 6), -1); // from is 6 + static_assert(m.indexIn(QStringView(u"hello🍉")) == 0); + static_assert(m.indexIn(QStringView(u"Hello🍉")) == 0); + static_assert(m.indexIn(QStringView(u"Hellohello🍉")) == 0); + static_assert(m.indexIn(QStringView(u"helloHello🍉")) == 0); + static_assert(m.indexIn(QStringView(u"he🍉")) == -1); + static_assert(m.indexIn(QStringView(u"hel🍉")) == 0); + static_assert(m.indexIn(QStringView(u"hellohello🍉"), 2) == 5); // from is 2 + static_assert(m.indexIn(QStringView(u"hellohello🍉"), 3) == 5); // from is 3 + static_assert(m.indexIn(QStringView(u"hellohello🍉"), 6) == -1); // from is 6 + } + { + static constexpr auto m = qMakeStaticCaseInsensitiveLatin1StringMatcher("Hel"); + QCOMPARE(m.indexIn(QStringView(u"hello🍉")), 0); + QCOMPARE(m.indexIn(QStringView(u"Hello🍉")), 0); + QCOMPARE(m.indexIn(QStringView(u"Hellohello🍉")), 0); + QCOMPARE(m.indexIn(QStringView(u"helloHello🍉")), 0); + QCOMPARE(m.indexIn(QStringView(u"he🍉")), -1); + QCOMPARE(m.indexIn(QStringView(u"hel🍉")), 0); + QCOMPARE(m.indexIn(hello), 0); + QCOMPARE(m.indexIn(hello, 1), -1); + QCOMPARE(m.indexIn(hello2, 2), hello.size()); // from is 2 + QCOMPARE(m.indexIn(hello2, 3), hello.size()); // from is 3 + QCOMPARE(m.indexIn(hello2, 6), -1); // from is 6 + static_assert(m.indexIn(QStringView(u"hello🍉")) == 0); + static_assert(m.indexIn(QStringView(u"Hello🍉")) == 0); + static_assert(m.indexIn(QStringView(u"Hellohello🍉")) == 0); + static_assert(m.indexIn(QStringView(u"helloHello🍉")) == 0); + static_assert(m.indexIn(QStringView(u"he🍉")) == -1); + static_assert(m.indexIn(QStringView(u"hel🍉")) == 0); + static_assert(m.indexIn(QStringView(u"hellohello🍉"), 2) == 5); // from is 2 + static_assert(m.indexIn(QStringView(u"hellohello🍉"), 3) == 5); // from is 3 + static_assert(m.indexIn(QStringView(u"hellohello🍉"), 6) == -1); // from is 6 + } + { + static constexpr auto m = qMakeStaticCaseInsensitiveLatin1StringMatcher("b\xF8"); + QCOMPARE(m.indexIn(QStringView(u"B\xD8")), 0); + QCOMPARE(m.indexIn(QStringView(u"B\xF8")), 0); + QCOMPARE(m.indexIn(QStringView(u"b\xD8")), 0); + QCOMPARE(m.indexIn(QStringView(u"b\xF8")), 0); + QCOMPARE(m.indexIn(QStringView(u"b\xF8lle")), 0); + QCOMPARE(m.indexIn(QStringView(u"m\xF8lle")), -1); + QCOMPARE(m.indexIn(QStringView(u"Si b\xF8")), 3); + } + { + static constexpr auto m = qMakeStaticCaseSensitiveLatin1StringMatcher("b\xF8"); + QCOMPARE(m.indexIn(QStringView(u"B\xD8")), -1); + QCOMPARE(m.indexIn(QStringView(u"B\xF8")), -1); + QCOMPARE(m.indexIn(QStringView(u"b\xD8")), -1); + QCOMPARE(m.indexIn(QStringView(u"b\xF8")), 0); + QCOMPARE(m.indexIn(QStringView(u"b\xF8lle")), 0); + QCOMPARE(m.indexIn(QStringView(u"m\xF8lle")), -1); + QCOMPARE(m.indexIn(QStringView(u"Si b\xF8")), 3); + } +#endif +} + void tst_QLatin1StringMatcher::interface() { QLatin1StringView needle = "abc123"_L1; @@ -387,25 +542,35 @@ void tst_QLatin1StringMatcher::haystacksWithMoreThan4GiBWork() QCOMPARE(large.size(), BaseSize + needle.size()); qDebug("created dataset in %lld ms", timer.elapsed()); - using MaybeThread = std::thread; - - // - // WHEN: trying to match an occurrence past the 4GiB mark - // - - qsizetype dynamicResult; - - auto t = MaybeThread{ [&] { - QLatin1StringMatcher m(QLatin1StringView(needle), Qt::CaseSensitive); - dynamicResult = m.indexIn(QLatin1StringView(large)); - } }; - t.join(); + { + // + // WHEN: trying to match an occurrence past the 4GiB mark + // + qsizetype dynamicResult; + auto t = std::thread{ [&] { + QLatin1StringMatcher m(QLatin1StringView(needle), Qt::CaseSensitive); + dynamicResult = m.indexIn(QLatin1StringView(large)); + } }; + t.join(); + + // + // THEN: the result index is not truncated + // + + QCOMPARE(dynamicResult, qsizetype(BaseSize)); + } - // - // THEN: the result index is not trucated - // + { + qsizetype dynamicResult; + auto t = std::thread{ [&] { + QLatin1StringMatcher m(QLatin1StringView(needle), Qt::CaseSensitive); + dynamicResult = m.indexIn(QStringView(QString::fromLatin1(large))); + } }; + t.join(); + + QCOMPARE(dynamicResult, qsizetype(BaseSize)); + } - QCOMPARE(dynamicResult, qsizetype(BaseSize)); #else QSKIP("This test is 64-bit only."); #endif diff --git a/tests/auto/corelib/text/qlocale/CMakeLists.txt b/tests/auto/corelib/text/qlocale/CMakeLists.txt index 3e6693d12b..a91dd44ea5 100644 --- a/tests/auto/corelib/text/qlocale/CMakeLists.txt +++ b/tests/auto/corelib/text/qlocale/CMakeLists.txt @@ -8,4 +8,6 @@ if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) endif() add_subdirectory(test) -add_subdirectory(syslocaleapp) +if(QT_FEATURE_jalalicalendar) + add_subdirectory(syslocaleapp) +endif() diff --git a/tests/auto/corelib/text/qlocale/tst_qlocale.cpp b/tests/auto/corelib/text/qlocale/tst_qlocale.cpp index c9668cd4d4..eb2d73b9b2 100644 --- a/tests/auto/corelib/text/qlocale/tst_qlocale.cpp +++ b/tests/auto/corelib/text/qlocale/tst_qlocale.cpp @@ -4178,6 +4178,8 @@ void tst_QLocale::mySystemLocale() qDebug("\n\t%s", qPrintable(QLocale::system().uiLanguages().join(u"\n\t"))); }); QCOMPARE(QLocale::system().uiLanguages(), uiLanguages); + QCOMPARE(QLocale::system().uiLanguages(QLocale::TagSeparator::Underscore), + uiLanguages.replaceInStrings(u"-", u"_")); reporter.dismiss(); } diff --git a/tests/auto/corelib/text/qregularexpression/CMakeLists.txt b/tests/auto/corelib/text/qregularexpression/CMakeLists.txt index b1d3ed0a8d..a7a7fe298f 100644 --- a/tests/auto/corelib/text/qregularexpression/CMakeLists.txt +++ b/tests/auto/corelib/text/qregularexpression/CMakeLists.txt @@ -14,4 +14,6 @@ endif() qt_internal_add_test(tst_qregularexpression SOURCES tst_qregularexpression.cpp + LIBRARIES + Qt::TestPrivate ) diff --git a/tests/auto/corelib/text/qregularexpression/tst_qregularexpression.cpp b/tests/auto/corelib/text/qregularexpression/tst_qregularexpression.cpp index 72c49d2a9c..d0ce414095 100644 --- a/tests/auto/corelib/text/qregularexpression/tst_qregularexpression.cpp +++ b/tests/auto/corelib/text/qregularexpression/tst_qregularexpression.cpp @@ -3,6 +3,7 @@ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include <QTest> +#include <QtTest/private/qcomparisontesthelper_p.h> #include <qstring.h> #include <qlist.h> #include <qstringlist.h> @@ -27,6 +28,7 @@ public: static void initMain(); private slots: + void compareCompiles(); void defaultConstructors(); void moveSemantics(); void moveSemanticsMatch(); @@ -460,6 +462,11 @@ void tst_QRegularExpression::initMain() } } +void tst_QRegularExpression::compareCompiles() +{ + QTestPrivate::testEqualityOperatorsCompile<QRegularExpression>(); +} + void tst_QRegularExpression::defaultConstructors() { QRegularExpression re; @@ -564,12 +571,12 @@ void tst_QRegularExpression::moveSemanticsMatchIterator() QRegularExpressionMatchIterator it1 = re.globalMatch("some test"); QVERIFY(it1.isValid()); QVERIFY(it1.hasNext()); - QCOMPARE(it1.regularExpression(), re); + QT_TEST_EQUALITY_OPS(it1.regularExpression(), re, true); QRegularExpressionMatchIterator it2(std::move(it1)); QVERIFY(it2.isValid()); QVERIFY(it2.hasNext()); - QCOMPARE(it2.regularExpression(), re); + QT_TEST_EQUALITY_OPS(it2.regularExpression(), re, true); consistencyCheck(it2); if (QTest::currentTestFailed()) return; @@ -578,13 +585,13 @@ void tst_QRegularExpression::moveSemanticsMatchIterator() QRegularExpressionMatchIterator it3 = re2.globalMatch("123test456"); QVERIFY(it3.isValid()); QVERIFY(it3.hasNext()); - QCOMPARE(it3.regularExpression(), re2); + QT_TEST_EQUALITY_OPS(it3.regularExpression(), re2, true); // check that (move)assigning to the moved-from object is ok it1 = std::move(it3); QVERIFY(it1.isValid()); QVERIFY(it1.hasNext()); - QCOMPARE(it1.regularExpression(), re2); + QT_TEST_EQUALITY_OPS(it1.regularExpression(), re2, true); consistencyCheck(it1); if (QTest::currentTestFailed()) return; @@ -1680,38 +1687,23 @@ void tst_QRegularExpression::serialize() static void verifyEquality(const QRegularExpression &re1, const QRegularExpression &re2) { - QVERIFY(re1 == re2); - QVERIFY(re2 == re1); + QT_TEST_EQUALITY_OPS(re1, re2, true); QCOMPARE(qHash(re1), qHash(re2)); - QVERIFY(!(re1 != re2)); - QVERIFY(!(re2 != re1)); QRegularExpression re3(re1); - QVERIFY(re1 == re3); - QVERIFY(re3 == re1); QCOMPARE(qHash(re1), qHash(re3)); - QVERIFY(!(re1 != re3)); - QVERIFY(!(re3 != re1)); + QT_TEST_EQUALITY_OPS(re1, re3, true); - QVERIFY(re2 == re3); - QVERIFY(re3 == re2); QCOMPARE(qHash(re2), qHash(re3)); - QVERIFY(!(re2 != re3)); - QVERIFY(!(re3 != re2)); + QT_TEST_EQUALITY_OPS(re2, re3, true); re3 = re2; - QVERIFY(re1 == re3); - QVERIFY(re3 == re1); QCOMPARE(qHash(re1), qHash(re3)); - QVERIFY(!(re1 != re3)); - QVERIFY(!(re3 != re1)); + QT_TEST_EQUALITY_OPS(re1, re3, true); - QVERIFY(re2 == re3); - QVERIFY(re3 == re2); QCOMPARE(qHash(re2), qHash(re3)); - QVERIFY(!(re2 != re3)); - QVERIFY(!(re3 != re2)); + QT_TEST_EQUALITY_OPS(re2, re3, true); } void tst_QRegularExpression::operatoreq_data() diff --git a/tests/auto/corelib/text/qstring/tst_qstring.cpp b/tests/auto/corelib/text/qstring/tst_qstring.cpp index d56a9ebd20..92ea5b013d 100644 --- a/tests/auto/corelib/text/qstring/tst_qstring.cpp +++ b/tests/auto/corelib/text/qstring/tst_qstring.cpp @@ -6647,9 +6647,41 @@ void tst_QString::arg() // number overloads QCOMPARE( s4.arg(0), QLatin1String("[0]") ); QCOMPARE( s4.arg(-1), QLatin1String("[-1]") ); + QCOMPARE( s4.arg(0U), QLatin1String("[0]")); + QCOMPARE( s4.arg(qint8(-128)), QLatin1String("[-128]")); // signed char + QCOMPARE( s4.arg(quint8(255)), QLatin1String("[255]")); // unsigned char + QCOMPARE( s4.arg(short(-4200)), QLatin1String("[-4200]")); + QCOMPARE( s4.arg(ushort(42000)), QLatin1String("[42000]")); QCOMPARE( s4.arg(4294967295UL), QLatin1String("[4294967295]") ); // ULONG_MAX 32 QCOMPARE( s4.arg(Q_INT64_C(9223372036854775807)), // LLONG_MAX QLatin1String("[9223372036854775807]") ); + QCOMPARE( s4.arg(Q_UINT64_C(9223372036854775808)), // LLONG_MAX + 1 + QLatin1String("[9223372036854775808]") ); + + // FP overloads + QCOMPARE(s4.arg(2.25), QLatin1String("[2.25]")); + QCOMPARE(s4.arg(3.75f), QLatin1String("[3.75]")); +#if !QFLOAT16_IS_NATIVE // QTBUG-126055 + QCOMPARE(s4.arg(qfloat16{4.125f}), QLatin1String("[4.125]")); +#endif + + // char-ish overloads + QCOMPARE(s4.arg('\xE4'), QStringView(u"[ä]")); + QEXPECT_FAIL("", "QTBUG-125588", Continue); + QCOMPARE(s4.arg(u'ø'), QStringView(u"[ø]")); +#ifdef Q_OS_WIN + QCOMPARE(QLatin1String("[%1]").arg(L'ø'), QStringView(u"[ø]")); +#endif + QEXPECT_FAIL("", "QTBUG-126054", Continue); + QCOMPARE(s4.arg(L'ø'), QStringView(u"[ø]")); +#ifndef __cpp_char8_t +#ifndef QT_NO_CAST_FROM_ASCII + QCOMPARE(QLatin1String("[%1]").arg(u8'a'), QLatin1String("[a]")); +#endif +#else + QEXPECT_FAIL("", "QTBUG-126053", Continue); +#endif + QCOMPARE(s4.arg(u8'a'), QLatin1String("[a]")); QTest::ignoreMessage(QtWarningMsg, "QString::arg: Argument missing: , foo"); QCOMPARE(QString().arg(foo), QString()); diff --git a/tests/auto/corelib/text/qstringapisymmetry/tst_qstringapisymmetry.cpp b/tests/auto/corelib/text/qstringapisymmetry/tst_qstringapisymmetry.cpp index 35a734cf02..06ef1aede0 100644 --- a/tests/auto/corelib/text/qstringapisymmetry/tst_qstringapisymmetry.cpp +++ b/tests/auto/corelib/text/qstringapisymmetry/tst_qstringapisymmetry.cpp @@ -545,6 +545,93 @@ private Q_SLOTS: void endsWith_QLatin1String_QLatin1Char() { endsWith_impl<QLatin1String, QLatin1Char>(); } private: + void arg1_data(bool argHasVariableLength = true) const; + template <typename Format, typename Argument> void arg1_impl() const; + +private Q_SLOTS: + // let Formats = {QString, QStringView, QLatin1String} + // let Arguments = Formats ∪ {QByteArray, const char*, const char8_t*. const char16_t*, std::u16string, char, QChar, QLatin1Char, char16_t} + // test Formats × Arguments: + void arg1_QString_QString_data() { arg1_data(); } + void arg1_QString_QString() { arg1_impl<QString, QString>(); } + void arg1_QString_QStringView_data() { arg1_data(); } + void arg1_QString_QStringView() { arg1_impl<QString, QStringView>(); } + void arg1_QString_QLatin1StringView_data() { arg1_data(); } + void arg1_QString_QLatin1StringView() { arg1_impl<QString, QLatin1StringView>(); } + void arg1_QString_QByteArray_data() { arg1_data(); } + void arg1_QString_QByteArray() { arg1_impl<QString, QByteArray>(); } + void arg1_QString_const_char_star_data() { arg1_data(); } + void arg1_QString_const_char_star() { arg1_impl<QString, const char*>(); } + void arg1_QString_const_char8_t_star_data() { arg1_data(); } + void arg1_QString_const_char8_t_star() { IF_CHAR8T((arg1_impl<QString, const char8_t*>())); } + void arg1_QString_const_char16_t_star_data() { arg1_data(); } + void arg1_QString_const_char16_t_star() { arg1_impl<QString, const char16_t*>(); } + void arg1_QString_stdu16string_data() { arg1_data(); } + void arg1_QString_stdu16string() { arg1_impl<QString, std::u16string>(); } + void arg1_QString_char_data() { arg1_data(false); } + void arg1_QString_char() { arg1_impl<QString, char>(); } + void arg1_QString_QChar_data() { arg1_data(false); } + void arg1_QString_QChar() { arg1_impl<QString, QChar>(); } + void arg1_QString_QLatin1Char_data() { arg1_data(false); } + void arg1_QString_QLatin1Char() { arg1_impl<QString, QLatin1Char>(); } + void arg1_QString_char16_t_data() { arg1_data(false); } + void arg1_QString_char16_t() { + QEXPECT_FAIL("%1/a", "QTBUG-125588", Continue); + QEXPECT_FAIL("%1/ä", "QTBUG-125588", Continue); + arg1_impl<QString, char16_t>(); + } + + void arg1_QStringView_QString_data() { arg1_data(); } + void arg1_QStringView_QString() { arg1_impl<QStringView, QString>(); } + void arg1_QStringView_QStringView_data() { arg1_data(); } + void arg1_QStringView_QStringView() { arg1_impl<QStringView, QStringView>(); } + void arg1_QStringView_QLatin1StringView_data() { arg1_data(); } + void arg1_QStringView_QLatin1StringView() { arg1_impl<QStringView, QLatin1StringView>(); } + void arg1_QStringView_QByteArray_data() { arg1_data(); } + void arg1_QStringView_QByteArray() { arg1_impl<QStringView, QByteArray>(); } + void arg1_QStringView_const_char_star_data() { arg1_data(); } + void arg1_QStringView_const_char_star() { arg1_impl<QStringView, const char*>(); } + void arg1_QStringView_const_char8_t_star_data() { arg1_data(); } + void arg1_QStringView_const_char8_t_star() { IF_CHAR8T((arg1_impl<QStringView, const char8_t*>())); } + void arg1_QStringView_const_char16_t_star_data() { arg1_data(); } + void arg1_QStringView_const_char16_t_star() { arg1_impl<QStringView, const char16_t*>(); } + void arg1_QStringView_stdu16string_data() { arg1_data(); } + void arg1_QStringView_stdu16string() { arg1_impl<QStringView, std::u16string>(); } + void arg1_QStringView_char_data() { arg1_data(false); } + void arg1_QStringView_char() { arg1_impl<QStringView, char>(); } + void arg1_QStringView_QChar_data() { arg1_data(false); } + void arg1_QStringView_QChar() { arg1_impl<QStringView, QChar>(); } + void arg1_QStringView_QLatin1Char_data() { arg1_data(false); } + void arg1_QStringView_QLatin1Char() { arg1_impl<QStringView, QLatin1Char>(); } + void arg1_QStringView_char16_t_data() { arg1_data(false); } + void arg1_QStringView_char16_t() { arg1_impl<QStringView, char16_t>(); } + + void arg1_QLatin1StringView_QString_data() { arg1_data(); } + void arg1_QLatin1StringView_QString() { arg1_impl<QLatin1StringView, QString>(); } + void arg1_QLatin1StringView_QStringView_data() { arg1_data(); } + void arg1_QLatin1StringView_QStringView() { arg1_impl<QLatin1StringView, QStringView>(); } + void arg1_QLatin1StringView_QLatin1StringView_data() { arg1_data(); } + void arg1_QLatin1StringView_QLatin1StringView() { arg1_impl<QLatin1StringView, QLatin1StringView>(); } + void arg1_QLatin1StringView_QByteArray_data() { arg1_data(); } + void arg1_QLatin1StringView_QByteArray() { arg1_impl<QLatin1StringView, QByteArray>(); } + void arg1_QLatin1StringView_const_char_star_data() { arg1_data(); } + void arg1_QLatin1StringView_const_char_star() { arg1_impl<QLatin1StringView, const char*>(); } + void arg1_QLatin1StringView_const_char8_t_star_data() { arg1_data(); } + void arg1_QLatin1StringView_const_char8_t_star() { IF_CHAR8T((arg1_impl<QLatin1StringView, const char8_t*>())); } + void arg1_QLatin1StringView_const_char16_t_star_data() { arg1_data(); } + void arg1_QLatin1StringView_const_char16_t_star() { arg1_impl<QLatin1StringView, const char16_t*>(); } + void arg1_QLatin1StringView_stdu16string_data() { arg1_data(); } + void arg1_QLatin1StringView_stdu16string() { arg1_impl<QLatin1StringView, std::u16string>(); } + void arg1_QLatin1StringView_char_data() { arg1_data(false); } + void arg1_QLatin1StringView_char() { arg1_impl<QLatin1StringView, char>(); } + void arg1_QLatin1StringView_QChar_data() { arg1_data(false); } + void arg1_QLatin1StringView_QChar() { arg1_impl<QLatin1StringView, QChar>(); } + void arg1_QLatin1StringView_QLatin1Char_data() { arg1_data(false); } + void arg1_QLatin1StringView_QLatin1Char() { arg1_impl<QLatin1StringView, QLatin1Char>(); } + void arg1_QLatin1StringView_char16_t_data() { arg1_data(false); } + void arg1_QLatin1StringView_char16_t() { arg1_impl<QLatin1StringView, char16_t>(); } + +private: void split_data(bool rhsHasVariableLength = true); template <typename Haystack, typename Needle> void split_impl() const; @@ -1112,6 +1199,10 @@ auto overload_s_v(QStringView s) { return s; } auto overload_sr_v(QString &&s) { return std::move(s); } auto overload_sr_v(QStringView s) { return s; } +Q_WEAK_OVERLOAD +auto overload_s_bav(const QString &s) { return s; } +auto overload_s_bav(QByteArrayView s) { return s; } + } // unnamed namespace template<typename T> @@ -1174,6 +1265,15 @@ void tst_QStringApiSymmetry::overload() overload_sr_v(CT()); } } + + if constexpr (std::is_convertible_v<T, QString> || std::is_convertible_v<T, QByteArrayView>) { + overload_s_bav(t); + overload_s_bav(ct); + if constexpr (!std::is_array_v<T>) { + overload_s_bav(T()); + overload_s_bav(CT()); + } + } QT_WARNING_POP } @@ -1290,6 +1390,7 @@ template <class Str> Str make(QStringView sf, QLatin1String l1, const QByteArra [[maybe_unused]] const QByteArray &u8) \ /*end*/ MAKE(QChar) { return sv.isEmpty() ? QChar() : sv.at(0); } +MAKE(char) { return sv.isEmpty() ? char() : char(sv.at(0).unicode()); } MAKE(char16_t) { return sv.isEmpty() ? char16_t() : char16_t{sv.at(0).unicode()}; } MAKE(QLatin1Char) { return l1.isEmpty() ? QLatin1Char('\0') : l1.at(0); } MAKE(QString) { return sv.toString(); } @@ -1298,6 +1399,9 @@ MAKE(QLatin1String) { return l1; } MAKE(QByteArray) { return u8; } MAKE(QByteArrayView) { return u8; } MAKE(const char *) { return u8.data(); } +#ifdef __cpp_char8_t +MAKE(const char8_t *) { return q_has_char8_t::QUtf8StringView(u8).data(); } +#endif MAKE(const char16_t *) { return sv.utf16(); } // assumes `sv` doesn't represent a substring MAKE(std::u16string) { return sv.toString().toStdU16String(); } MAKE(QUtf8StringView) { return u8; } @@ -1926,6 +2030,69 @@ void tst_QStringApiSymmetry::endsWith_impl() const QCOMPARE_EQ(haystack.endsWith(needle, Qt::CaseInsensitive), resultCIS); } +void tst_QStringApiSymmetry::arg1_data(bool argHasVariableLength) const +{ + QTest::addColumn<QString>("formatU16"); + QTest::addColumn<QString>("argumentU16"); + QTest::addColumn<QString>("expected"); + + const char *null = nullptr; + const char *empty = ""; + + auto row = [](const char *fmt, const char *arg, const char *res) { + auto protect = [](const char *s) { return s ? *s ? s : "<empty>" : "<null>"; }; + QTest::addRow("%s/%s", protect(fmt), protect(arg)) + << QString::fromUtf8(fmt) << QString::fromUtf8(arg) << QString::fromUtf8(res); + }; + + for (auto fmt : {null, empty}) { + if (argHasVariableLength) { + for (auto arg : {null, empty}) + row(fmt, arg, ""); + } + for (auto arg : {"a", "ä"}) + row(fmt, arg, ""); + if (argHasVariableLength) { + for (auto arg : {"äá", "Øåß"}) + row(fmt, arg, ""); + } + } + + for (auto fmt : {"%1"}) { + if (argHasVariableLength) { + for (auto arg : {null, empty}) + row(fmt, arg, arg); + } + for (auto arg : {"a", "ä"}) + row(fmt, arg, arg); + if (argHasVariableLength) { + for (auto arg : {"äá", "Øåß"}) + row(fmt, arg, arg); + } + } +} + +template <typename Format, typename Argument> +void tst_QStringApiSymmetry::arg1_impl() const +{ + QFETCH(const QString, formatU16); + QFETCH(const QString, argumentU16); + QFETCH(const QString, expected); + + const auto formatL1Pinned = formatU16.toLatin1(); + const auto formatL1 = QLatin1StringView{formatL1Pinned}; + const auto formatU8 = formatU16.toUtf8(); + + const auto argumentL1Pinned = argumentU16.toLatin1(); + const auto argumentL1= QLatin1StringView{argumentL1Pinned}; + const auto argumentU8 = argumentU16.toUtf8(); + + const auto format = make<Format>(formatU16, formatL1, formatU8); + const auto argument = make<Argument>(argumentU16, argumentL1, argumentU8); + + QCOMPARE(format.arg(argument), expected); +} + void tst_QStringApiSymmetry::split_data(bool rhsHasVariableLength) { QTest::addColumn<QStringView>("haystackU16"); diff --git a/tests/auto/corelib/text/qstringbuilder/qstringbuilder1/stringbuilder.cpp b/tests/auto/corelib/text/qstringbuilder/qstringbuilder1/stringbuilder.cpp index 59362d010a..7931363b4b 100644 --- a/tests/auto/corelib/text/qstringbuilder/qstringbuilder1/stringbuilder.cpp +++ b/tests/auto/corelib/text/qstringbuilder/qstringbuilder1/stringbuilder.cpp @@ -377,6 +377,8 @@ void runScenario() char chararray[3] = { 'H', 'i', '\0' }; const char constchararray[3] = { 'H', 'i', '\0' }; char achar = 'a'; + char embedded_NULs[16] = { 'H', 'i' }; + const char const_embedded_NULs[16] = { 'H', 'i' }; CHECK(P, bytearray, bytearray); CHECK(P, QByteArray(bytearray), bytearray); @@ -400,6 +402,33 @@ void runScenario() CHECK(P, bytearray, achar); CHECK(Q, bytearray, constchararray); CHECK(Q, bytearray, achar); + CHECK(Q, bytearray, embedded_NULs); + CHECK(Q, bytearray, const_embedded_NULs); + + CHECK(Q, baview, bytearray); + CHECK(Q, baview, charstar); + CHECK(Q, baview, chararray); + CHECK(Q, baview, constchararray); + CHECK(Q, baview, achar); + CHECK(Q, baview, embedded_NULs); + CHECK(Q, baview, const_embedded_NULs); + + // Check QString/QByteArray consistency when appending const char[] with embedded NULs: + { + const QByteArray ba = baview Q embedded_NULs; + QEXPECT_FAIL("", "QTBUG-117321", Continue); + QCOMPARE(ba.size(), baview.size() + q20::ssize(embedded_NULs) - 1); + +#ifndef QT_NO_CAST_FROM_ASCII + const auto l1s = QLatin1StringView{baview}; // l1string != baview + + const QString s = l1s Q embedded_NULs; + QCOMPARE(s.size(), l1s.size() + q20::ssize(embedded_NULs) - 1); + + QEXPECT_FAIL("", "QTBUG-117321", Continue); + QCOMPARE(s, ba); +#endif + } //CHECK(Q, charstar, charstar); // BUILTIN <-> BUILTIN cat't be overloaded //CHECK(Q, charstar, chararray); diff --git a/tests/auto/corelib/text/qstringbuilder/qstringbuilder1/tst_qstringbuilder1.cpp b/tests/auto/corelib/text/qstringbuilder/qstringbuilder1/tst_qstringbuilder1.cpp index 394372c398..e8365f500b 100644 --- a/tests/auto/corelib/text/qstringbuilder/qstringbuilder1/tst_qstringbuilder1.cpp +++ b/tests/auto/corelib/text/qstringbuilder/qstringbuilder1/tst_qstringbuilder1.cpp @@ -15,6 +15,8 @@ #include <QtCore/QStringBuilder> #include <QtTest/QTest> +#include <QtCore/q20iterator.h> + #define LITERAL "some literal" namespace { diff --git a/tests/auto/corelib/text/qstringbuilder/qstringbuilder2/tst_qstringbuilder2.cpp b/tests/auto/corelib/text/qstringbuilder/qstringbuilder2/tst_qstringbuilder2.cpp index dc590304f5..1aaee114a3 100644 --- a/tests/auto/corelib/text/qstringbuilder/qstringbuilder2/tst_qstringbuilder2.cpp +++ b/tests/auto/corelib/text/qstringbuilder/qstringbuilder2/tst_qstringbuilder2.cpp @@ -16,6 +16,8 @@ #include <QtCore/QStringBuilder> #include <QtTest/QTest> +#include <QtCore/q20iterator.h> + #define LITERAL "some literal" namespace { diff --git a/tests/auto/corelib/text/qstringbuilder/qstringbuilder3/tst_qstringbuilder3.cpp b/tests/auto/corelib/text/qstringbuilder/qstringbuilder3/tst_qstringbuilder3.cpp index 3222b52713..aaa14a5d1a 100644 --- a/tests/auto/corelib/text/qstringbuilder/qstringbuilder3/tst_qstringbuilder3.cpp +++ b/tests/auto/corelib/text/qstringbuilder/qstringbuilder3/tst_qstringbuilder3.cpp @@ -15,6 +15,8 @@ #include <QtCore/QStringBuilder> #include <QtTest/QTest> +#include <QtCore/q20iterator.h> + #define LITERAL "some literal" namespace { diff --git a/tests/auto/corelib/text/qstringbuilder/qstringbuilder4/tst_qstringbuilder4.cpp b/tests/auto/corelib/text/qstringbuilder/qstringbuilder4/tst_qstringbuilder4.cpp index 442c5275d2..319708fd4b 100644 --- a/tests/auto/corelib/text/qstringbuilder/qstringbuilder4/tst_qstringbuilder4.cpp +++ b/tests/auto/corelib/text/qstringbuilder/qstringbuilder4/tst_qstringbuilder4.cpp @@ -16,6 +16,8 @@ #include <QtCore/QStringBuilder> #include <QtTest/QTest> +#include <QtCore/q20iterator.h> + #define LITERAL "some literal" namespace { diff --git a/tests/auto/corelib/text/qstringconverter/tst_qstringconverter.cpp b/tests/auto/corelib/text/qstringconverter/tst_qstringconverter.cpp index ed3f91ac94..342c343a42 100644 --- a/tests/auto/corelib/text/qstringconverter/tst_qstringconverter.cpp +++ b/tests/auto/corelib/text/qstringconverter/tst_qstringconverter.cpp @@ -257,7 +257,7 @@ void tst_QStringConverter::invalidConverter() QVERIFY(!encoder.hasError()); char buffer[100]; char *position = encoder.appendToBuffer(buffer, u"Even more"); - QCOMPARE(position, buffer); + QCOMPARE(position - buffer, 0); QVERIFY(encoder.hasError()); } @@ -283,7 +283,7 @@ void tst_QStringConverter::invalidConverter() QVERIFY(!decoder.hasError()); char16_t buffer[100]; char16_t *position = decoder.appendToBuffer(buffer, "Even more"); - QCOMPARE(position, buffer); + QCOMPARE(position - buffer, 0); QVERIFY(decoder.hasError()); } } diff --git a/tests/auto/corelib/text/qstringview/CMakeLists.txt b/tests/auto/corelib/text/qstringview/CMakeLists.txt index ba5f540838..b541cdd0ed 100644 --- a/tests/auto/corelib/text/qstringview/CMakeLists.txt +++ b/tests/auto/corelib/text/qstringview/CMakeLists.txt @@ -18,5 +18,12 @@ qt_internal_add_test(tst_qstringview Qt::CorePrivate ) +if(QT_FEATURE_sanitize_undefined) + qt_internal_extend_target(tst_qstringview + DEFINES + QT_SANITIZE_UNDEFINED # GCC (in)famously doesn't provide a predefined macro for this + ) +endif() + ## Scopes: ##################################################################### diff --git a/tests/auto/corelib/text/qstringview/tst_qstringview.cpp b/tests/auto/corelib/text/qstringview/tst_qstringview.cpp index df3ef94371..3f87ffc9fc 100644 --- a/tests/auto/corelib/text/qstringview/tst_qstringview.cpp +++ b/tests/auto/corelib/text/qstringview/tst_qstringview.cpp @@ -359,6 +359,30 @@ void tst_QStringView::constExpr() const static_assert(sv3.isEmpty()); static_assert(sv3.size() == 0); } +#if !defined(Q_CC_GNU_ONLY) || !defined(QT_SANITIZE_UNDEFINED) + // Below checks are disabled because of a compilation issue with GCC and + // -fsanitize=undefined. See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71962. + { + static constexpr char16_t hello[] = u"Hello"; + constexpr QStringView sv(hello); + static_assert(sv.size() == 5); + static_assert(!sv.empty()); + static_assert(!sv.isEmpty()); + static_assert(!sv.isNull()); + static_assert(*sv.utf16() == 'H'); + static_assert(sv[0] == QLatin1Char('H')); + static_assert(sv.at(0) == QLatin1Char('H')); + static_assert(sv.front() == QLatin1Char('H')); + static_assert(sv.first() == QLatin1Char('H')); + static_assert(sv[4] == QLatin1Char('o')); + static_assert(sv.at(4) == QLatin1Char('o')); + static_assert(sv.back() == QLatin1Char('o')); + static_assert(sv.last() == QLatin1Char('o')); + + constexpr auto sv2 = QStringView::fromArray(hello); + QCOMPARE_EQ(sv, sv2.chopped(1)); + } +#endif // -fsanitize=undefined } void tst_QStringView::basics() const @@ -430,7 +454,7 @@ void tst_QStringView::fromArray() const { static constexpr char16_t hello[] = u"Hello\0abc\0\0."; - constexpr QStringView sv = QStringView::fromArray(hello); + const QStringView sv = QStringView::fromArray(hello); QCOMPARE(sv.size(), 13); QVERIFY(!sv.empty()); QVERIFY(!sv.isEmpty()); |