diff options
author | Ulf Hermann <ulf.hermann@qt.io> | 2023-01-31 13:53:44 +0100 |
---|---|---|
committer | Ulf Hermann <ulf.hermann@qt.io> | 2023-02-02 15:57:09 +0100 |
commit | 41248f259005aa3052d569def9f873afee4ac8f6 (patch) | |
tree | 216562ae545e0ec41a69bb366d6d4f182a311402 /tests | |
parent | b2912174572dea2a7bff59414418d602ef58a00a (diff) |
moc: Allow calling ctors on pre-allocated data
When calling a ctor this way, an object is created in the memory pointed
to by _a[0] using the other arguments for the ctor.
This allows separate allocation and initialization of an object through
the metaobject system.
Fixes: QTBUG-108879
Change-Id: Ifb154373ee42faab281cfb62aa14334980ec6b7d
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Diffstat (limited to 'tests')
-rw-r--r-- | tests/auto/tools/moc/tst_moc.cpp | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/tests/auto/tools/moc/tst_moc.cpp b/tests/auto/tools/moc/tst_moc.cpp index 35c31b6b87..abe3b0abbb 100644 --- a/tests/auto/tools/moc/tst_moc.cpp +++ b/tests/auto/tools/moc/tst_moc.cpp @@ -758,6 +758,7 @@ private slots: void setQPRopertyBinding(); void privateQPropertyShim(); void readWriteThroughBindable(); + void invokableCtors(); signals: void sigWithUnsignedArg(unsigned foo); @@ -4424,6 +4425,42 @@ void tst_Moc::readWriteThroughBindable() } } +struct WithInvokableCtor +{ + Q_GADGET + Q_PROPERTY(int thing MEMBER m_thing CONSTANT FINAL) +public: + WithInvokableCtor() = default; + Q_INVOKABLE WithInvokableCtor(int theThing) : m_thing(theThing) {} + + int m_thing = 10; +}; + +void tst_Moc::invokableCtors() +{ + const QMetaType metaType = QMetaType::fromType<WithInvokableCtor>(); + Q_ASSERT(metaType.sizeOf() > 0); + const QMetaObject *metaObject = metaType.metaObject(); + QVERIFY(metaObject); + + QCOMPARE(metaObject->constructorCount(), 1); + WithInvokableCtor *result = nullptr; + const auto guard = qScopeGuard([&]() { delete result; }); + int argument = 17; + void *a[] = { &result, &argument }; + metaObject->static_metacall(QMetaObject::CreateInstance, 0, a); + QVERIFY(result); + QCOMPARE(result->m_thing, 17); + + // Call dtor so that we're left with "uninitialized" memory. + WithInvokableCtor result2; + result2.~WithInvokableCtor(); + + void *b[] = { &result2, &argument }; + metaObject->static_metacall(QMetaObject::ConstructInPlace, 0, b); + QCOMPARE(result2.m_thing, 17); +} + QTEST_MAIN(tst_Moc) // the generated code must compile with QT_NO_KEYWORDS |