summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Brasser <mbrasser@ford.com>2017-11-21 12:18:56 -0600
committerFrederik Gladhorn <frederik.gladhorn@qt.io>2017-11-28 14:26:22 +0000
commitcc46992fbb94f1775ac22aa23b42d76f810a5913 (patch)
tree1cd305e40235b6d114e3e65b74211ce0890e35ca
parent19f54245d35ee5eb66b991274908f780b103e3b4 (diff)
Fix issue with circular singleton instantiationsv5.10.0-rc2
While a recursion check exists and works, it can lead to instanting the same singleton multiple times (leaking all but one copy). Change-Id: Icf342aad71c5cb225488262341517d95786e1f84 Reviewed-by: Erik Verbruggen <erik.verbruggen@qt.io> Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
-rw-r--r--src/qml/qml/qqmlmetatype.cpp4
-rw-r--r--tests/auto/qml/qqmllanguage/data/circularSingleton.qml6
-rw-r--r--tests/auto/qml/qqmllanguage/data/singleton/circular/MySingleton.qml12
-rw-r--r--tests/auto/qml/qqmllanguage/data/singleton/circular/qmldir1
-rw-r--r--tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp17
5 files changed, 39 insertions, 1 deletions
diff --git a/src/qml/qml/qqmlmetatype.cpp b/src/qml/qml/qqmlmetatype.cpp
index 8e6be538ef..0f388cf7b7 100644
--- a/src/qml/qml/qqmlmetatype.cpp
+++ b/src/qml/qml/qqmlmetatype.cpp
@@ -274,8 +274,10 @@ void QQmlType::SingletonInstanceInfo::init(QQmlEngine *e)
QQmlData::ensurePropertyCache(e, o);
} else if (!url.isEmpty() && !qobjectApi(e)) {
QQmlComponent component(e, url, QQmlComponent::PreferSynchronous);
- QObject *o = component.create();
+ QObject *o = component.beginCreate(e->rootContext());
setQObjectApi(e, o);
+ if (o)
+ component.completeCreate();
}
v4->popContext();
}
diff --git a/tests/auto/qml/qqmllanguage/data/circularSingleton.qml b/tests/auto/qml/qqmllanguage/data/circularSingleton.qml
new file mode 100644
index 0000000000..e569111956
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/circularSingleton.qml
@@ -0,0 +1,6 @@
+import QtQuick 2.10
+import "singleton/circular"
+
+QtObject {
+ property int value: MySingleton.value
+}
diff --git a/tests/auto/qml/qqmllanguage/data/singleton/circular/MySingleton.qml b/tests/auto/qml/qqmllanguage/data/singleton/circular/MySingleton.qml
new file mode 100644
index 0000000000..1253018789
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/singleton/circular/MySingleton.qml
@@ -0,0 +1,12 @@
+pragma Singleton
+import QtQuick 2.10
+
+QtObject {
+ enum MyEnum {
+ Value0,
+ Value1,
+ Value2
+ }
+
+ property int value: MySingleton.Value2
+}
diff --git a/tests/auto/qml/qqmllanguage/data/singleton/circular/qmldir b/tests/auto/qml/qqmllanguage/data/singleton/circular/qmldir
new file mode 100644
index 0000000000..3bc50738dd
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/singleton/circular/qmldir
@@ -0,0 +1 @@
+singleton MySingleton MySingleton.qml
diff --git a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
index 21efb0336d..7fb4c809f7 100644
--- a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
+++ b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
@@ -240,6 +240,7 @@ private slots:
void compositeSingletonJavaScriptPragma();
void compositeSingletonSelectors();
void compositeSingletonRegistered();
+ void compositeSingletonCircular();
void customParserBindingScopes();
void customParserEvaluateEnum();
@@ -4211,6 +4212,22 @@ void tst_qqmllanguage::compositeSingletonRegistered()
verifyCompositeSingletonPropertyValues(o, "value1", 925, "value2", 755);
}
+void tst_qqmllanguage::compositeSingletonCircular()
+{
+ QQmlComponent component(&engine, testFile("circularSingleton.qml"));
+ VERIFY_ERRORS(0);
+
+ QQmlTestMessageHandler messageHandler;
+
+ QObject *o = component.create();
+ QVERIFY(o != 0);
+
+ // ensure we aren't hitting the recursion warning
+ QVERIFY2(messageHandler.messages().isEmpty(), qPrintable(messageHandler.messageString()));
+
+ QCOMPARE(o->property("value").toInt(), 2);
+}
+
void tst_qqmllanguage::customParserBindingScopes()
{
QQmlComponent component(&engine, testFile("customParserBindingScopes.qml"));