diff --git a/src/corelib/kernel/qvariant.cpp b/src/corelib/kernel/qvariant.cpp index a2711a48f85..94d062f6332 100644 --- a/src/corelib/kernel/qvariant.cpp +++ b/src/corelib/kernel/qvariant.cpp @@ -220,7 +220,7 @@ static void customConstruct(QVariant::Private *d, const void *copy) *d = QVariant::Private(); return; } - if (!(iface->copyCtr && iface->defaultCtr)) { + if (!iface->copyCtr || (!copy && !iface->defaultCtr)) { // QVariant requires type to be copy and default constructible *d = QVariant::Private(); qWarning("QVariant: Provided metatype does not support " diff --git a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp index 240c25ae480..f20fd0cd878 100644 --- a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp +++ b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp @@ -289,6 +289,7 @@ private slots: void constructFromIncompatibleMetaType_data(); void constructFromIncompatibleMetaType(); + void copyNonDefaultConstructible(); private: void dataStream_data(QDataStream::Version version); @@ -5110,11 +5111,19 @@ void tst_QVariant::equalsWithoutMetaObject() QVERIFY(qobjectVariant != noMetaObjectVariant); } -class NonDefaultConstructible +struct NonDefaultConstructible { - NonDefaultConstructible(int ) {} + NonDefaultConstructible(int i) :i(i) {} + int i; + friend bool operator==(NonDefaultConstructible l, NonDefaultConstructible r) + { return l.i == r.i; } }; +template <> char *QTest::toString(const NonDefaultConstructible &ndc) +{ + return qstrdup('{' + QByteArray::number(ndc.i) + '}'); +} + struct Indestructible { Indestructible() {} @@ -5154,5 +5163,23 @@ void tst_QVariant::constructFromIncompatibleMetaType() QVERIFY(!QVariant(regular).convert(type)); } +void tst_QVariant::copyNonDefaultConstructible() +{ + NonDefaultConstructible ndc(42); + QVariant var(QMetaType::fromType(), &ndc); + QVERIFY(var.isDetached()); + QCOMPARE(var.metaType(), QMetaType::fromType()); + QVERIFY(var.constData() != &ndc); + + // qvariant_cast and QVariant::value don't compile + QCOMPARE(*static_cast(var.constData()), ndc); + + QVariant var2 = var; + var2.detach(); // force another copy + QVERIFY(var2.isDetached()); + QVERIFY(var2.constData() != var.constData()); + QCOMPARE(var2, var); +} + QTEST_MAIN(tst_QVariant) #include "tst_qvariant.moc"