Do not store non relocatable types in QVariants internal storage

This mostly reverts change 76e8e8e9c8.
The reason is that storing non relocatable types inline in
QVariants storage would implicitly make QVariant non relocatable.

Fixes: QTBUG-87686
Change-Id: I2a09b1dcdd907d60085dccf17f987086dcba878c
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
bb10
Lars Knoll 2020-10-20 10:22:07 +02:00
parent 194f0ab50c
commit 1e0f2be5ac
3 changed files with 33 additions and 5 deletions

View File

@ -255,7 +255,7 @@ static void customConstruct(QVariant::Private *d, const void *copy)
return;
}
if (QVariant::Private::canUseInternalSpace(size, type.alignOf())) {
if (QVariant::Private::canUseInternalSpace(type)) {
type.construct(&d->data, copy);
d->is_shared = false;
} else {

View File

@ -442,9 +442,12 @@ class Q_CORE_EXPORT QVariant
{
static constexpr size_t MaxInternalSize = 3*sizeof(void *);
template<typename T>
static constexpr bool CanUseInternalSpace = (sizeof(T) <= MaxInternalSize && alignof(T) <= alignof(double));
static constexpr bool canUseInternalSpace(size_t s, size_t align)
{ return s <= MaxInternalSize && align <= alignof(double); }
static constexpr bool CanUseInternalSpace = (QTypeInfo<T>::isRelocatable && sizeof(T) <= MaxInternalSize && alignof(T) <= alignof(double));
static constexpr bool canUseInternalSpace(QMetaType type)
{
return type.flags() & QMetaType::RelocatableType &&
size_t(type.sizeOf()) <= MaxInternalSize && size_t(type.alignOf()) <= alignof(double);
}
union
{

View File

@ -284,6 +284,8 @@ private slots:
void preferDirectConversionOverInterfaces();
void mutableView();
void moveOperations();
private:
void dataStream_data(QDataStream::Version version);
void loadQVariantFromDataStream(QDataStream::Version version);
@ -1926,7 +1928,7 @@ void tst_QVariant::userType()
QCOMPARE(instanceCount, 3);
{
QVariant second = myCarrier;
QCOMPARE(instanceCount, 4);
QCOMPARE(instanceCount, 3);
second.detach();
QCOMPARE(instanceCount, 4);
}
@ -4961,5 +4963,28 @@ void tst_QVariant::mutableView()
QCOMPARE(extracted.text, nullptr);
}
void tst_QVariant::moveOperations()
{
{
QString str = "Hello";
auto v = QVariant::fromValue(str);
QVariant v2(std::move(v));
QCOMPARE(v2.toString(), str);
v = QVariant::fromValue(str);
v2 = std::move(v);
QCOMPARE(v2.toString(), str);
}
std::list<int> list;
auto v = QVariant::fromValue(list);
QVariant v2(std::move(v));
QVERIFY(v2.value<std::list<int>>() == list);
v = QVariant::fromValue(list);
v2 = std::move(v);
QVERIFY(v2.value<std::list<int>>() == list);
}
QTEST_MAIN(tst_QVariant)
#include "tst_qvariant.moc"