From d752da1857358726b89027ac039c20c1cd696b36 Mon Sep 17 00:00:00 2001 From: Ivan Solovev Date: Fri, 1 Sep 2023 13:48:30 +0200 Subject: [PATCH] QAnyStringView: fix construction from QL1SV for bootstrapped builds The SizeShift was not taken into account when constructing QASV from QL1SV. This is not an issue in normal Qt builds, because SizeShift == 0 there. But in bootstrapped case (and in future Qt 7) SizeShift changes to 2, and the bug becomes visible. The added test-cases do not really reveal the issue, because we do not run tests in bootstrapped builds, but at least they will help to prevent the issues in Qt 7. Pick-to: 6.6 6.5 6.2 Change-Id: I337b37b5230323a5357f48fd1c9bf799ca507d52 Reviewed-by: Fabian Kosmale Reviewed-by: Thiago Macieira --- src/corelib/text/qstring.h | 2 +- .../qanystringview/tst_qanystringview.cpp | 28 +++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/src/corelib/text/qstring.h b/src/corelib/text/qstring.h index 1f83a50f55..149fb6b289 100644 --- a/src/corelib/text/qstring.h +++ b/src/corelib/text/qstring.h @@ -89,7 +89,7 @@ qsizetype QStringView::count(QLatin1StringView s, Qt::CaseSensitivity cs) const // constexpr QAnyStringView::QAnyStringView(QLatin1StringView str) noexcept - : m_data{str.data()}, m_size{size_t(str.size()) | Tag::Latin1} {} + : m_data{str.data()}, m_size{size_t(str.size() << SizeShift) | Tag::Latin1} {} constexpr QLatin1StringView QAnyStringView::asLatin1StringView() const { diff --git a/tests/auto/corelib/text/qanystringview/tst_qanystringview.cpp b/tests/auto/corelib/text/qanystringview/tst_qanystringview.cpp index 95beec4321..989bc8c798 100644 --- a/tests/auto/corelib/text/qanystringview/tst_qanystringview.cpp +++ b/tests/auto/corelib/text/qanystringview/tst_qanystringview.cpp @@ -253,9 +253,15 @@ static_assert(CanConvert); #endif // QT_CONFIG(cpp_winrt) +// In bootstrapped build and in Qt 7+, two lower bits of size() are used as a +// mask, so check that it is handled correctly, and the mask does not break the +// actual size template struct SampleStrings { static constexpr char emptyString[] = ""; + static constexpr char oneChar[] = "a"; + static constexpr char twoChars[] = "ab"; + static constexpr char threeChars[] = "abc"; static constexpr char regularString[] = "Hello World!"; static constexpr char regularLongString[] = R"(Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna @@ -271,6 +277,9 @@ id est laborum.)"; template <> struct SampleStrings { static constexpr char16_t emptyString[] = u""; + static constexpr char16_t oneChar[] = u"a"; + static constexpr char16_t twoChars[] = u"ab"; + static constexpr char16_t threeChars[] = u"abc"; static constexpr char16_t regularString[] = u"Hello World!"; static constexpr char16_t regularLongString[] = uR"(Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna @@ -286,11 +295,20 @@ id est laborum.)"; template <> struct SampleStrings { static constexpr QChar emptyString[] = { {} }; // this one is easy + static const QChar *const oneChar; + static const QChar *const twoChars; + static const QChar *const threeChars; static const QChar *const regularString; static const QChar *const regularLongString; static const QChar *const stringWithNulls; static constexpr qsizetype stringWithNullsLength = SampleStrings::stringWithNullsLength; }; +const QChar *const SampleStrings::oneChar = + reinterpret_cast(SampleStrings::oneChar); +const QChar *const SampleStrings::twoChars = + reinterpret_cast(SampleStrings::twoChars); +const QChar *const SampleStrings::threeChars = + reinterpret_cast(SampleStrings::threeChars); const QChar *const SampleStrings::regularString = reinterpret_cast(SampleStrings::regularString); const QChar *const SampleStrings::regularLongString = @@ -312,6 +330,7 @@ private Q_SLOTS: void fromQByteArray() const { fromQStringOrByteArray(); } void fromQStringView() const { fromQStringOrByteArray(); } void fromQUtf8StringView() const { fromQStringOrByteArray(); } + void fromQLatin1StringView() const { fromQStringOrByteArray(); } void fromCharArray() const { fromArray(); } void fromChar8Array() const { ONLY_IF_CHAR_8_T(fromArray()); } @@ -616,6 +635,15 @@ void tst_QAnyStringView::fromQStringOrByteArray() const QVERIFY( QAnyStringView(empty).isEmpty()); QVERIFY(!QAnyStringView(empty).isNull()); + conversion_tests(QStringOrByteArray(Strings::oneChar)); + if (QTest::currentTestFailed()) + return; + conversion_tests(QStringOrByteArray(Strings::twoChars)); + if (QTest::currentTestFailed()) + return; + conversion_tests(QStringOrByteArray(Strings::threeChars)); + if (QTest::currentTestFailed()) + return; conversion_tests(QStringOrByteArray(Strings::regularString)); if (QTest::currentTestFailed()) return;