QVariants of null pointers should be null
Changes the QVariant::isNull() implementation for pointer types so they return true if null. [ChangeLog][QVariant] QVariants containing pointers will now return true on isNull() if the contained pointer is null. Change-Id: I8aa0dab482403837073fb2f376a46126cc3bc6b2 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
parent
341bfcd1ea
commit
f2c6e10ad5
@ -1177,7 +1177,17 @@ static void customClear(QVariant::Private *d)
|
||||
|
||||
static bool customIsNull(const QVariant::Private *d)
|
||||
{
|
||||
return d->is_null;
|
||||
if (d->is_null)
|
||||
return true;
|
||||
const char *const typeName = QMetaType::typeName(d->type);
|
||||
if (Q_UNLIKELY(!typeName) && Q_LIKELY(!QMetaType::isRegistered(d->type)))
|
||||
qFatal("QVariant::isNull: type %d unknown to QVariant.", d->type);
|
||||
uint typeNameLen = qstrlen(typeName);
|
||||
if (typeNameLen > 0 && typeName[typeNameLen - 1] == '*') {
|
||||
const void *d_ptr = d->is_shared ? d->data.shared->ptr : &(d->data.ptr);
|
||||
return *static_cast<void *const *>(d_ptr) == nullptr;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool customCompare(const QVariant::Private *a, const QVariant::Private *b)
|
||||
@ -3740,9 +3750,10 @@ void* QVariant::data()
|
||||
|
||||
/*!
|
||||
Returns \c true if this is a null variant, false otherwise. A variant is
|
||||
considered null if it contains no initialized value or it contains an instance
|
||||
of built-in type that has an isNull method, in which case the result would be
|
||||
the same as calling isNull on the wrapped object.
|
||||
considered null if it contains no initialized value, or the contained value
|
||||
is a null pointer or is an instance of a built-in type that has an isNull
|
||||
method, in which case the result would be the same as calling isNull on the
|
||||
wrapped object.
|
||||
|
||||
\warning Null variants is not a single state and two null variants may easily
|
||||
return \c false on the == operator if they do not contain similar null values.
|
||||
|
@ -187,6 +187,16 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct PrimitiveIsNull<T*>
|
||||
{
|
||||
public:
|
||||
static bool isNull(const QVariant::Private *d)
|
||||
{
|
||||
return d->is_null || d->data.ptr == nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct PrimitiveIsNull<std::nullptr_t>
|
||||
{
|
||||
|
@ -371,6 +371,8 @@ void tst_QVariant::copy_constructor()
|
||||
QVERIFY(var8.isNull());
|
||||
}
|
||||
|
||||
Q_DECLARE_METATYPE(int*)
|
||||
|
||||
void tst_QVariant::isNull()
|
||||
{
|
||||
QVariant var;
|
||||
@ -413,6 +415,18 @@ void tst_QVariant::isNull()
|
||||
QVERIFY(var9.isNull());
|
||||
var9 = QVariant::fromValue<QJsonValue>(QJsonValue(QJsonValue::Null));
|
||||
QVERIFY(var9.isNull());
|
||||
|
||||
QVariant var10(QMetaType::VoidStar, nullptr);
|
||||
QVERIFY(var10.isNull());
|
||||
var10 = QVariant::fromValue<void*>(nullptr);
|
||||
QVERIFY(var10.isNull());
|
||||
|
||||
QVariant var11(QMetaType::QObjectStar, nullptr);
|
||||
QVERIFY(var11.isNull());
|
||||
var11 = QVariant::fromValue<QObject*>(nullptr);
|
||||
QVERIFY(var11.isNull());
|
||||
|
||||
QVERIFY(QVariant::fromValue<int*>(nullptr).isNull());
|
||||
}
|
||||
|
||||
void tst_QVariant::swap()
|
||||
@ -2650,7 +2664,7 @@ void tst_QVariant::qvariant_cast_QObject_data()
|
||||
QTest::newRow("null QObject") << QVariant::fromValue<QObject*>(0) << true << true;
|
||||
QTest::newRow("null derived QObject") << QVariant::fromValue<CustomQObject*>(0) << true << true;
|
||||
QTest::newRow("null custom object") << QVariant::fromValue<CustomNonQObject*>(0) << false << true;
|
||||
QTest::newRow("null int") << QVariant::fromValue<int>(0) << false << true;
|
||||
QTest::newRow("zero int") << QVariant::fromValue<int>(0) << false << false;
|
||||
}
|
||||
|
||||
void tst_QVariant::qvariant_cast_QObject()
|
||||
@ -2668,12 +2682,14 @@ void tst_QVariant::qvariant_cast_QObject()
|
||||
QVERIFY(data.canConvert(QMetaType::QObjectStar));
|
||||
QVERIFY(data.canConvert(::qMetaTypeId<QObject*>()));
|
||||
QCOMPARE(data.value<QObject*>() == 0, isNull);
|
||||
QCOMPARE(data.isNull(), isNull);
|
||||
QVERIFY(data.convert(QMetaType::QObjectStar));
|
||||
QCOMPARE(data.userType(), int(QMetaType::QObjectStar));
|
||||
} else {
|
||||
QVERIFY(!data.canConvert<QObject*>());
|
||||
QVERIFY(!data.canConvert(QMetaType::QObjectStar));
|
||||
QVERIFY(!data.canConvert(::qMetaTypeId<QObject*>()));
|
||||
QCOMPARE(data.isNull(), isNull);
|
||||
QVERIFY(!data.value<QObject*>());
|
||||
QVERIFY(!data.convert(QMetaType::QObjectStar));
|
||||
QVERIFY(data.userType() != QMetaType::QObjectStar);
|
||||
@ -3752,7 +3768,7 @@ void tst_QVariant::moreCustomTypes()
|
||||
{
|
||||
int i = 5;
|
||||
PLAY_WITH_VARIANT((void *)(&i), false, QString(), 0, false);
|
||||
PLAY_WITH_VARIANT((void *)(0), false, QString(), 0, false);
|
||||
PLAY_WITH_VARIANT((void *)(0), true, QString(), 0, false);
|
||||
}
|
||||
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user