summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/corelib/kernel/qvariant.cpp19
-rw-r--r--src/corelib/kernel/qvariant_p.h10
-rw-r--r--tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp20
3 files changed, 43 insertions, 6 deletions
diff --git a/src/corelib/kernel/qvariant.cpp b/src/corelib/kernel/qvariant.cpp
index b73c83bc49..a6b92f9f8f 100644
--- a/src/corelib/kernel/qvariant.cpp
+++ b/src/corelib/kernel/qvariant.cpp
@@ -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.
diff --git a/src/corelib/kernel/qvariant_p.h b/src/corelib/kernel/qvariant_p.h
index 487949431c..75c269d710 100644
--- a/src/corelib/kernel/qvariant_p.h
+++ b/src/corelib/kernel/qvariant_p.h
@@ -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>
{
diff --git a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp
index 906587248e..a5973276f2 100644
--- a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp
+++ b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp
@@ -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);
}
{