diff options
author | Fabian Kosmale <fabian.kosmale@qt.io> | 2021-02-19 18:47:11 +0100 |
---|---|---|
committer | Fabian Kosmale <fabian.kosmale@qt.io> | 2021-02-26 09:10:31 +0100 |
commit | 9d6ba110e8f98463d136fa97993db6d1968479c1 (patch) | |
tree | 501110a06ff6310d78fc0d176804c3a5af12d888 /tests/auto/corelib | |
parent | 50e857a9cbb2d41a85e85e1c10e18bd761569b88 (diff) |
QMetaType: Store QMetaObject for pointer to const QObject, too
Before this change, the QMetaType for T const* where T is derived from
QObject would not store the static QMetaObject of T. This commit changes
this. As a consequence, the metatype system can now convert between
const and non-const pointers to QObject. Note that this allows casting
const away; but so does C++ with const_cast.
In addition, a new flag, QMetaType::IsImmutable is introduced, and used
to tag the metatypes of pointer to const types. This allows code to
discern between pointers to mutable and const QObjects, which is
relevant for the QML engine.
Task-number: QTBUG-82354
Change-Id: I3e4e4f39f565bd99a65e161528ce5304df73d6d6
Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
Diffstat (limited to 'tests/auto/corelib')
-rw-r--r-- | tests/auto/corelib/kernel/qmetatype/tst_qmetatype.h | 6 | ||||
-rw-r--r-- | tests/auto/corelib/kernel/qmetatype/tst_qmetatype2.cpp | 14 | ||||
-rw-r--r-- | tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp | 30 |
3 files changed, 50 insertions, 0 deletions
diff --git a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.h b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.h index 2a0e177be1..fecd5d75c6 100644 --- a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.h +++ b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.h @@ -31,6 +31,11 @@ #include "tst_qmetatype_common.h" #include "tst_qvariant_common.h" +struct Derived : QObject +{ + Q_OBJECT +}; + struct MessageHandlerCustom : public MessageHandler { MessageHandlerCustom(const int typeId) @@ -118,6 +123,7 @@ private slots: void constRefs(); void convertCustomType_data(); void convertCustomType(); + void convertConstNonConst(); void compareCustomEqualOnlyType(); void customDebugStream(); void unknownType(); diff --git a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype2.cpp b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype2.cpp index 3c097ad0d8..856b56941a 100644 --- a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype2.cpp +++ b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype2.cpp @@ -278,6 +278,20 @@ void tst_QMetaType::convertCustomType() QCOMPARE(v.value<CustomConvertibleType2>().m_foo, testCustom.m_foo); } +void tst_QMetaType::convertConstNonConst() +{ + auto mtConstObj = QMetaType::fromType<QObject const*>(); + auto mtObj = QMetaType::fromType<QObject *>(); + auto mtConstDerived = QMetaType::fromType<Derived const*>(); + auto mtDerived = QMetaType::fromType<Derived *>(); + + QVERIFY(QMetaType::canConvert(mtConstObj, mtObj)); + QVERIFY(QMetaType::canConvert(mtObj, mtConstObj)); // casting const away is allowed (but can lead to UB) + QVERIFY(QMetaType::canConvert(mtConstDerived, mtObj)); + QVERIFY(QMetaType::canConvert(mtDerived, mtConstObj)); + QVERIFY(QMetaType::canConvert(mtObj, mtConstDerived)); +} + void tst_QMetaType::compareCustomEqualOnlyType() { QMetaType type = QMetaType::fromType<CustomEqualsOnlyType>(); diff --git a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp index 23ee85ee46..2883a47852 100644 --- a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp +++ b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp @@ -59,6 +59,7 @@ #include <QEasingCurve> #include <QSequentialIterable> #include <QAssociativeIterable> +#include <QScopeGuard> #include "qnumeric.h" #include <private/qlocale_p.h> @@ -253,6 +254,7 @@ private slots: void convertByteArrayToBool() const; void convertByteArrayToBool_data() const; void convertIterables() const; + void convertConstNonConst() const; void toIntFromQString() const; void toIntFromDouble() const; void setValue(); @@ -3136,6 +3138,34 @@ void tst_QVariant::convertIterables() const } } +struct Derived : QObject +{ + Q_OBJECT +}; + +void tst_QVariant::convertConstNonConst() const +{ + Derived *derived = new Derived; + QObject *obj = derived; + QObject const *unrelatedConstObj = new QObject; + auto cleanUp = qScopeGuard([&] { + delete unrelatedConstObj; + delete derived; + }); + QObject const *constObj = obj; + Derived const *constDerived = derived; + QCOMPARE(QVariant::fromValue(constObj).value<QObject *>(), obj); + QCOMPARE(QVariant::fromValue(obj).value<QObject const *>(), constObj); + + QCOMPARE(QVariant::fromValue(constDerived).value<QObject *>(), derived); + QCOMPARE(QVariant::fromValue(derived).value<QObject const *>(), derived); + + QObject const *derivedAsConstObject = derived; + // up cast and remove const is possible, albeit dangerous + QCOMPARE(QVariant::fromValue(derivedAsConstObject).value<Derived *>(), derived); + QCOMPARE(QVariant::fromValue(unrelatedConstObj).value<Derived *>(), nullptr); +} + /*! We verify that: 1. Converting the string "9.9" to int fails. This is the behavior of |