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 <fabian.kosmale@qt.io>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
bb10
Ivan Solovev 2023-09-01 13:48:30 +02:00
parent d85663ced8
commit d752da1857
2 changed files with 29 additions and 1 deletions

View File

@ -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
{

View File

@ -253,9 +253,15 @@ static_assert(CanConvert<const winrt::hstring&>);
#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 <typename Char> 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<char16_t>
{
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<QChar>
{
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<char16_t>::stringWithNullsLength;
};
const QChar *const SampleStrings<QChar>::oneChar =
reinterpret_cast<const QChar *>(SampleStrings<char16_t>::oneChar);
const QChar *const SampleStrings<QChar>::twoChars =
reinterpret_cast<const QChar *>(SampleStrings<char16_t>::twoChars);
const QChar *const SampleStrings<QChar>::threeChars =
reinterpret_cast<const QChar *>(SampleStrings<char16_t>::threeChars);
const QChar *const SampleStrings<QChar>::regularString =
reinterpret_cast<const QChar *>(SampleStrings<char16_t>::regularString);
const QChar *const SampleStrings<QChar>::regularLongString =
@ -312,6 +330,7 @@ private Q_SLOTS:
void fromQByteArray() const { fromQStringOrByteArray<QByteArray>(); }
void fromQStringView() const { fromQStringOrByteArray<QStringView>(); }
void fromQUtf8StringView() const { fromQStringOrByteArray<QUtf8StringView>(); }
void fromQLatin1StringView() const { fromQStringOrByteArray<QLatin1StringView>(); }
void fromCharArray() const { fromArray<char>(); }
void fromChar8Array() const { ONLY_IF_CHAR_8_T(fromArray<char8_t>()); }
@ -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;