Merge branch 'master' into el6

This commit is contained in:
Rex Dieter 2016-06-16 09:19:32 -05:00
commit 1f012c49ac
8 changed files with 656 additions and 1 deletions

View File

@ -0,0 +1,99 @@
From 6371b208a9e55845090dcd34234e314c6587c105 Mon Sep 17 00:00:00 2001
From: Simon Hausmann <simon.hausmann@theqtcompany.com>
Date: Tue, 17 May 2016 15:18:12 +0200
Subject: [PATCH 07/40] Revert "Remove this piece of code"
This reverts commit bad007360a0f6fba304d8f4c99826a1250fd886c.
The lookup in the global object is necessary to detect whether we've seen any
unresolved properties. This is used for the optimization of skipping binding
refresh updates when a context property changes.
Task-number: QTBUG-53431
Change-Id: Idb39a32e4b58b915496bbb9d8a098dc17a6f688a
Reviewed-by: Lars Knoll <lars.knoll@theqtcompany.com>
---
src/qml/qml/qqmlcontextwrapper.cpp | 13 +++++++++++--
tests/auto/qml/qqmlcontext/data/qtbug_53431.qml | 7 +++++++
tests/auto/qml/qqmlcontext/tst_qqmlcontext.cpp | 14 ++++++++++++++
3 files changed, 32 insertions(+), 2 deletions(-)
create mode 100644 tests/auto/qml/qqmlcontext/data/qtbug_53431.qml
diff --git a/src/qml/qml/qqmlcontextwrapper.cpp b/src/qml/qml/qqmlcontextwrapper.cpp
index 0d84c3b..e3770a7 100644
--- a/src/qml/qml/qqmlcontextwrapper.cpp
+++ b/src/qml/qml/qqmlcontextwrapper.cpp
@@ -99,14 +99,23 @@ ReturnedValue QmlContextWrapper::get(const Managed *m, String *name, bool *hasPr
QV4::ExecutionEngine *v4 = resource->engine();
QV4::Scope scope(v4);
+ // In V8 the JS global object would come _before_ the QML global object,
+ // so simulate that here.
+ bool hasProp;
+ QV4::ScopedValue result(scope, v4->globalObject->get(name, &hasProp));
+ if (hasProp) {
+ if (hasProperty)
+ *hasProperty = hasProp;
+ return result->asReturnedValue();
+ }
+
if (resource->d()->isNullWrapper)
return Object::get(m, name, hasProperty);
if (v4->callingQmlContext() != resource->d()->context)
return Object::get(m, name, hasProperty);
- bool hasProp;
- QV4::ScopedValue result(scope, Object::get(m, name, &hasProp));
+ result = Object::get(m, name, &hasProp);
if (hasProp) {
if (hasProperty)
*hasProperty = hasProp;
diff --git a/tests/auto/qml/qqmlcontext/data/qtbug_53431.qml b/tests/auto/qml/qqmlcontext/data/qtbug_53431.qml
new file mode 100644
index 0000000..2ceee2b
--- /dev/null
+++ b/tests/auto/qml/qqmlcontext/data/qtbug_53431.qml
@@ -0,0 +1,7 @@
+import QtQml 2.0
+QtObject {
+ property int value: {
+ console.log("lookup in global object")
+ return 1
+ }
+}
diff --git a/tests/auto/qml/qqmlcontext/tst_qqmlcontext.cpp b/tests/auto/qml/qqmlcontext/tst_qqmlcontext.cpp
index 18ef7ac..d338e6f 100644
--- a/tests/auto/qml/qqmlcontext/tst_qqmlcontext.cpp
+++ b/tests/auto/qml/qqmlcontext/tst_qqmlcontext.cpp
@@ -61,6 +61,7 @@ private slots:
void refreshExpressions();
void refreshExpressionsCrash();
void refreshExpressionsRootContext();
+ void skipExpressionRefresh_qtbug_53431();
void qtbug_22535();
void evalAfterInvalidate();
@@ -642,6 +643,19 @@ void tst_qqmlcontext::refreshExpressionsRootContext()
delete o1;
}
+void tst_qqmlcontext::skipExpressionRefresh_qtbug_53431()
+{
+ QQmlEngine engine;
+ QQmlComponent component(&engine, testFileUrl("qtbug_53431.qml"));
+ QScopedPointer<QObject> object(component.create(0));
+ QVERIFY(!object.isNull());
+ QCOMPARE(object->property("value").toInt(), 1);
+ object->setProperty("value", 10);
+ QCOMPARE(object->property("value").toInt(), 10);
+ engine.rootContext()->setContextProperty("randomContextProperty", 42);
+ QCOMPARE(object->property("value").toInt(), 10);
+}
+
void tst_qqmlcontext::qtbug_22535()
{
QQmlEngine engine;
--
1.9.3

View File

@ -0,0 +1,67 @@
From 82b0b31fe47a6a54c500f2cbea45b37fc28f3bee Mon Sep 17 00:00:00 2001
From: Filipe Azevedo <filipe.azevedo@kdab.com>
Date: Mon, 2 May 2016 13:11:26 +0200
Subject: [PATCH 10/40] Fix crash for unknown QQmlListModel roles in debug
builds
If a role is unknown, trying to access it will crash in getExistingRole.
Fixed that and now return QVariant() for unknown roles.
Change-Id: Iad5c1292a4faee893fbc5a69984cf776aca85d70
Reviewed-by: Shawn Rutledge <shawn.rutledge@theqtcompany.com>
Reviewed-by: Robin Burchell <robin.burchell@viroteck.net>
---
src/qml/types/qqmllistmodel.cpp | 2 ++
tests/auto/qml/qqmllistmodel/tst_qqmllistmodel.cpp | 16 ++++++++++++++++
2 files changed, 18 insertions(+)
diff --git a/src/qml/types/qqmllistmodel.cpp b/src/qml/types/qqmllistmodel.cpp
index 4b0aa47..3d71621 100644
--- a/src/qml/types/qqmllistmodel.cpp
+++ b/src/qml/types/qqmllistmodel.cpp
@@ -392,6 +392,8 @@ void ListModel::updateCacheIndices()
QVariant ListModel::getProperty(int elementIndex, int roleIndex, const QQmlListModel *owner, QV4::ExecutionEngine *eng)
{
+ if (roleIndex >= m_layout->roleCount())
+ return QVariant();
ListElement *e = elements[elementIndex];
const ListLayout::Role &r = m_layout->getExistingRole(roleIndex);
return e->getProperty(r, owner, eng);
diff --git a/tests/auto/qml/qqmllistmodel/tst_qqmllistmodel.cpp b/tests/auto/qml/qqmllistmodel/tst_qqmllistmodel.cpp
index d26c1c5..6b1dece 100644
--- a/tests/auto/qml/qqmllistmodel/tst_qqmllistmodel.cpp
+++ b/tests/auto/qml/qqmllistmodel/tst_qqmllistmodel.cpp
@@ -110,6 +110,7 @@ private slots:
void get_nested();
void get_nested_data();
void crash_model_with_multiple_roles();
+ void crash_model_with_unknown_roles();
void set_model_cache();
void property_changes();
void property_changes_data();
@@ -968,6 +969,21 @@ void tst_qqmllistmodel::crash_model_with_multiple_roles()
delete rootItem;
}
+void tst_qqmllistmodel::crash_model_with_unknown_roles()
+{
+ QQmlEngine eng;
+ QQmlComponent component(&eng, testFileUrl("multipleroles.qml"));
+ QScopedPointer<QObject> rootItem(component.create());
+ QVERIFY(component.errorString().isEmpty());
+ QVERIFY(rootItem != 0);
+ QQmlListModel *model = rootItem->findChild<QQmlListModel*>("listModel");
+ QVERIFY(model != 0);
+
+ // used to cause a crash in debug builds
+ model->index(0, 0, QModelIndex()).data(Qt::DisplayRole);
+ model->index(0, 0, QModelIndex()).data(Qt::UserRole);
+}
+
//QTBUG-15190
void tst_qqmllistmodel::set_model_cache()
{
--
1.9.3

View File

@ -0,0 +1,37 @@
From 40a80ec9d712d8c40ebd6a6373322c3332ff5b50 Mon Sep 17 00:00:00 2001
From: Laszlo Agocs <laszlo.agocs@theqtcompany.com>
Date: Mon, 23 May 2016 16:01:44 +0200
Subject: [PATCH 11/40] Avoid Canvas crashes with qtquickcompiler
Change-Id: Ic87052308706b8ef71e2f27837abfbaea57c43cc
Task-number: QTBUG-49692
Reviewed-by: Mitch Curtis <mitch.curtis@qt.io>
---
src/quick/items/context2d/qquickcanvasitem.cpp | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/src/quick/items/context2d/qquickcanvasitem.cpp b/src/quick/items/context2d/qquickcanvasitem.cpp
index 9fb49f9..47ac2c4 100644
--- a/src/quick/items/context2d/qquickcanvasitem.cpp
+++ b/src/quick/items/context2d/qquickcanvasitem.cpp
@@ -675,10 +675,14 @@ void QQuickCanvasItem::itemChange(QQuickItem::ItemChange change, const QQuickIte
QSGRenderContext *context = QQuickWindowPrivate::get(d->window)->context;
// Rendering to FramebufferObject needs a valid OpenGL context.
- if (context != 0 && (d->renderTarget != FramebufferObject || context->isValid()))
- sceneGraphInitialized();
- else
+ if (context != 0 && (d->renderTarget != FramebufferObject || context->isValid())) {
+ // Defer the call. In some (arguably incorrect) cases we get here due
+ // to ItemSceneChange with the user-supplied property values not yet
+ // set. Work this around by a deferred invoke. (QTBUG-49692)
+ QMetaObject::invokeMethod(this, "sceneGraphInitialized", Qt::QueuedConnection);
+ } else {
connect(d->window, SIGNAL(sceneGraphInitialized()), SLOT(sceneGraphInitialized()));
+ }
}
void QQuickCanvasItem::updatePolish()
--
1.9.3

View File

@ -0,0 +1,155 @@
From 7dcda224fe73cb51a29e8946afd641a989d7209a Mon Sep 17 00:00:00 2001
From: Simon Hausmann <simon.hausmann@qt.io>
Date: Wed, 25 May 2016 16:22:44 +0200
Subject: [PATCH 16/40] Fix crash with SignalTransition
Don't crash when using SignalTransition with a signal object instead of the
slot used to emit the signal. A signal object is just as good.
Task-number: QTBUG-53596
Change-Id: I8a419d16ec0c257c9a798a83ee5bad338794cdd2
Reviewed-by: Michael Brasser <michael.brasser@live.com>
---
src/imports/statemachine/signaltransition.cpp | 26 ++++++--
src/qml/jsruntime/qv4qobjectwrapper_p.h | 2 +-
.../qmltest/statemachine/tst_signaltransition.qml | 76 ++++++++++++++++++++++
3 files changed, 96 insertions(+), 8 deletions(-)
create mode 100644 tests/auto/qmltest/statemachine/tst_signaltransition.qml
diff --git a/src/imports/statemachine/signaltransition.cpp b/src/imports/statemachine/signaltransition.cpp
index 33ee11c..4f6c769 100644
--- a/src/imports/statemachine/signaltransition.cpp
+++ b/src/imports/statemachine/signaltransition.cpp
@@ -105,15 +105,27 @@ void SignalTransition::setSignal(const QJSValue &signal)
QV4::ExecutionEngine *jsEngine = QV8Engine::getV4(QQmlEngine::contextForObject(this)->engine());
QV4::Scope scope(jsEngine);
- QV4::Scoped<QV4::QObjectMethod> qobjectSignal(scope, QJSValuePrivate::convertedToValue(jsEngine, m_signal));
- Q_ASSERT(qobjectSignal);
-
- QObject *sender = qobjectSignal->object();
- Q_ASSERT(sender);
- QMetaMethod metaMethod = sender->metaObject()->method(qobjectSignal->methodIndex());
+ QObject *sender;
+ QMetaMethod signalMethod;
+
+ QV4::ScopedValue value(scope, QJSValuePrivate::convertedToValue(jsEngine, m_signal));
+
+ // Did we get the "slot" that can be used to invoke the signal?
+ if (QV4::QObjectMethod *signalSlot = value->as<QV4::QObjectMethod>()) {
+ sender = signalSlot->object();
+ Q_ASSERT(sender);
+ signalMethod = sender->metaObject()->method(signalSlot->methodIndex());
+ } else if (QV4::QmlSignalHandler *signalObject = value->as<QV4::QmlSignalHandler>()) { // or did we get the signal object (the one with the connect()/disconnect() functions) ?
+ sender = signalObject->object();
+ Q_ASSERT(sender);
+ signalMethod = sender->metaObject()->method(signalObject->signalIndex());
+ } else {
+ qmlInfo(this) << tr("Specified signal does not exist.");
+ return;
+ }
QSignalTransition::setSenderObject(sender);
- QSignalTransition::setSignal(metaMethod.methodSignature());
+ QSignalTransition::setSignal(signalMethod.methodSignature());
connectTriggered();
}
diff --git a/src/qml/jsruntime/qv4qobjectwrapper_p.h b/src/qml/jsruntime/qv4qobjectwrapper_p.h
index 1126013..0fc39b2 100644
--- a/src/qml/jsruntime/qv4qobjectwrapper_p.h
+++ b/src/qml/jsruntime/qv4qobjectwrapper_p.h
@@ -166,7 +166,7 @@ struct Q_QML_EXPORT QObjectMethod : public QV4::FunctionObject
static void markObjects(Heap::Base *that, QV4::ExecutionEngine *e);
};
-struct QmlSignalHandler : public QV4::Object
+struct Q_QML_EXPORT QmlSignalHandler : public QV4::Object
{
V4_OBJECT2(QmlSignalHandler, QV4::Object)
V4_PROTOTYPE(signalHandlerPrototype)
diff --git a/tests/auto/qmltest/statemachine/tst_signaltransition.qml b/tests/auto/qmltest/statemachine/tst_signaltransition.qml
new file mode 100644
index 0000000..0e35207
--- /dev/null
+++ b/tests/auto/qmltest/statemachine/tst_signaltransition.qml
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Ford Motor Company
+** Copyright (C) 2016 The Qt Company
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtTest 1.1
+import QtQml.StateMachine 1.0
+
+TestCase {
+ id: testCase
+ StateMachine {
+ id: machine
+ initialState: startState
+ State {
+ id: startState
+ SignalTransition {
+ id: signalTrans
+ signal: testCase.onMysignal
+ targetState: finalState
+ }
+ }
+ FinalState {
+ id: finalState
+ }
+ }
+
+ SignalSpy {
+ id: finalStateActive
+ target: finalState
+ signalName: "activeChanged"
+ }
+
+ signal mysignal()
+
+ name: "testSignalTransition"
+ function test_signalTransition()
+ {
+ // Start statemachine, should not have reached finalState yet.
+ machine.start()
+ tryCompare(finalStateActive, "count", 0)
+ tryCompare(machine, "running", true)
+
+ testCase.mysignal()
+ tryCompare(finalStateActive, "count", 1)
+ tryCompare(machine, "running", false)
+ }
+}
--
1.9.3

View File

@ -0,0 +1,141 @@
From 7039db4885a143f8f1d363c9b71665e9160d3d55 Mon Sep 17 00:00:00 2001
From: Filippo Cucchetto <filippocucchetto@gmail.com>
Date: Thu, 2 Jun 2016 21:49:37 +0200
Subject: [PATCH 24/40] Revert removal of "Fixed MouseArea threshold with
preventStealing"
This reverts commit 9c8dab537819f0d999e680490c2d125b8836cbbb
where commit e1400b5b4d8311769ad3b9f631479ee2b0271197 was removed
due to the breakage of QtLocation tests.
After some hours of debugging it seems that the problem in QtLocation
was due to filtering of mouse move events in QDeclarativeGeoMapItemBase.
See QTBUG-52075
Task-number: QTBUG-52534
Change-Id: I00f002c1d6f60f74a148b5a6ac2b9f63e93718a9
Reviewed-by: Paolo Angelelli <paolo.angelelli@theqtcompany.com>
Reviewed-by: Michal Klocek <michal.klocek@theqtcompany.com>
---
src/quick/items/qquickmousearea.cpp | 21 +++++++++++++--------
src/quick/items/qquickmousearea_p_p.h | 1 +
.../quick/qquickmousearea/tst_qquickmousearea.cpp | 11 +++++++++++
3 files changed, 25 insertions(+), 8 deletions(-)
diff --git a/src/quick/items/qquickmousearea.cpp b/src/quick/items/qquickmousearea.cpp
index ef053ab..d66e55a 100644
--- a/src/quick/items/qquickmousearea.cpp
+++ b/src/quick/items/qquickmousearea.cpp
@@ -52,7 +52,7 @@ DEFINE_BOOL_CONFIG_OPTION(qmlVisualTouchDebugging, QML_VISUAL_TOUCH_DEBUGGING)
QQuickMouseAreaPrivate::QQuickMouseAreaPrivate()
: enabled(true), scrollGestureEnabled(true), hovered(false), longPress(false),
moved(false), stealMouse(false), doubleClick(false), preventStealing(false),
- propagateComposedEvents(false), pressed(0)
+ propagateComposedEvents(false), overThreshold(false), pressed(0)
#ifndef QT_NO_DRAGANDDROP
, drag(0)
#endif
@@ -715,7 +715,7 @@ void QQuickMouseArea::mouseMoveEvent(QMouseEvent *event)
curLocalPos = event->windowPos();
}
- if (keepMouseGrab() && d->stealMouse && !d->drag->active())
+ if (keepMouseGrab() && d->stealMouse && d->overThreshold && !d->drag->active())
d->drag->setActive(true);
QPointF startPos = d->drag->target()->parentItem()
@@ -741,16 +741,19 @@ void QQuickMouseArea::mouseMoveEvent(QMouseEvent *event)
if (d->drag->active())
d->drag->target()->setPosition(dragPos);
- if (!keepMouseGrab()
- && (QQuickWindowPrivate::dragOverThreshold(dragPos.x() - startPos.x(), Qt::XAxis, event, d->drag->threshold())
- || QQuickWindowPrivate::dragOverThreshold(dragPos.y() - startPos.y(), Qt::YAxis, event, d->drag->threshold()))) {
- setKeepMouseGrab(true);
- d->stealMouse = true;
-
+ if (!d->overThreshold && (QQuickWindowPrivate::dragOverThreshold(dragPos.x() - startPos.x(), Qt::XAxis, event, d->drag->threshold())
+ || QQuickWindowPrivate::dragOverThreshold(dragPos.y() - startPos.y(), Qt::YAxis, event, d->drag->threshold())))
+ {
+ d->overThreshold = true;
if (d->drag->smoothed())
d->startScene = event->windowPos();
}
+ if (!keepMouseGrab() && d->overThreshold) {
+ setKeepMouseGrab(true);
+ d->stealMouse = true;
+ }
+
d->moved = true;
}
#endif
@@ -767,6 +770,7 @@ void QQuickMouseArea::mouseReleaseEvent(QMouseEvent *event)
{
Q_D(QQuickMouseArea);
d->stealMouse = false;
+ d->overThreshold = false;
if (!d->enabled && !d->pressed) {
QQuickItem::mouseReleaseEvent(event);
} else {
@@ -875,6 +879,7 @@ void QQuickMouseArea::ungrabMouse()
d->pressed = 0;
d->stealMouse = false;
d->doubleClick = false;
+ d->overThreshold = false;
setKeepMouseGrab(false);
#ifndef QT_NO_DRAGANDDROP
diff --git a/src/quick/items/qquickmousearea_p_p.h b/src/quick/items/qquickmousearea_p_p.h
index 014729b..f63c5f6 100644
--- a/src/quick/items/qquickmousearea_p_p.h
+++ b/src/quick/items/qquickmousearea_p_p.h
@@ -86,6 +86,7 @@ public:
bool doubleClick : 1;
bool preventStealing : 1;
bool propagateComposedEvents : 1;
+ bool overThreshold : 1;
Qt::MouseButtons pressed;
#ifndef QT_NO_DRAGANDDROP
QQuickDrag *drag;
diff --git a/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp b/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp
index 82c053d..9cdfd21 100644
--- a/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp
+++ b/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp
@@ -79,6 +79,7 @@ private slots:
void dragging_data() { acceptedButton_data(); }
void dragging();
void dragSmoothed();
+ void dragThreshold_data();
void dragThreshold();
void invalidDrag_data() { rejectedButton_data(); }
void invalidDrag();
@@ -375,8 +376,17 @@ void tst_QQuickMouseArea::dragSmoothed()
QTest::mouseRelease(&window, Qt::LeftButton, 0, QPoint(100, 122));
}
+void tst_QQuickMouseArea::dragThreshold_data()
+{
+ QTest::addColumn<bool>("preventStealing");
+ QTest::newRow("without preventStealing") << false;
+ QTest::newRow("with preventStealing") << true;
+}
+
void tst_QQuickMouseArea::dragThreshold()
{
+ QFETCH(bool, preventStealing);
+
QQuickView window;
QByteArray errorMessage;
QVERIFY2(initView(window, testFileUrl("dragging.qml"), true, &errorMessage), errorMessage.constData());
@@ -386,6 +396,7 @@ void tst_QQuickMouseArea::dragThreshold()
QVERIFY(window.rootObject() != 0);
QQuickMouseArea *mouseRegion = window.rootObject()->findChild<QQuickMouseArea*>("mouseregion");
+ mouseRegion->setPreventStealing(preventStealing);
QQuickDrag *drag = mouseRegion->drag();
drag->setThreshold(5);
--
1.9.3

View File

@ -0,0 +1,75 @@
From 6d54a59bd725ba83e758236c5ff0fc7855109dac Mon Sep 17 00:00:00 2001
From: Simon Hausmann <simon.hausmann@qt.io>
Date: Thu, 2 Jun 2016 15:57:41 +0200
Subject: [PATCH 27/40] Fix crash when using with statement with an expression
that throws
We need to evaluate the expression for the "with" statement that is supposed to
define the new scope _before_ opening up the scope, otherwise - when the
evaluation of the expression throws an exception - we'll try to pop the "with"
scope we couldn't open in the first place.
[ChangeLog][QtQml] Fix crash when using the "with" statement with an expression
that throws an exception.
Task-number: QTBUG-53794
Change-Id: I7733f5a4c5d844916302b9a91c789a0f6b421e8a
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
---
src/qml/compiler/qv4codegen.cpp | 5 +++--
tests/auto/qml/qjsengine/tst_qjsengine.cpp | 9 +++++++++
2 files changed, 12 insertions(+), 2 deletions(-)
diff --git a/src/qml/compiler/qv4codegen.cpp b/src/qml/compiler/qv4codegen.cpp
index ea82d07..c14163a 100644
--- a/src/qml/compiler/qv4codegen.cpp
+++ b/src/qml/compiler/qv4codegen.cpp
@@ -2718,6 +2718,9 @@ bool Codegen::visit(WithStatement *ast)
_function->hasWith = true;
+ const int withObject = _block->newTemp();
+ _block->MOVE(_block->TEMP(withObject), *expression(ast->expression));
+
// need an exception handler for with to cleanup the with scope
IR::BasicBlock *withExceptionHandler = _function->newBasicBlock(exceptionHandler());
withExceptionHandler->EXP(withExceptionHandler->CALL(withExceptionHandler->NAME(IR::Name::builtin_pop_scope, 0, 0), 0));
@@ -2732,8 +2735,6 @@ bool Codegen::visit(WithStatement *ast)
_block->JUMP(withBlock);
_block = withBlock;
- int withObject = _block->newTemp();
- _block->MOVE(_block->TEMP(withObject), *expression(ast->expression));
IR::ExprList *args = _function->New<IR::ExprList>();
args->init(_block->TEMP(withObject));
_block->EXP(_block->CALL(_block->NAME(IR::Name::builtin_push_with_scope, 0, 0), args));
diff --git a/tests/auto/qml/qjsengine/tst_qjsengine.cpp b/tests/auto/qml/qjsengine/tst_qjsengine.cpp
index 9a0865c..8594aec 100644
--- a/tests/auto/qml/qjsengine/tst_qjsengine.cpp
+++ b/tests/auto/qml/qjsengine/tst_qjsengine.cpp
@@ -193,6 +193,8 @@ private slots:
void v4FunctionWithoutQML();
+ void withNoContext();
+
signals:
void testSignal();
};
@@ -3840,6 +3842,13 @@ void tst_QJSEngine::v4FunctionWithoutQML()
QVERIFY(obj.called);
}
+void tst_QJSEngine::withNoContext()
+{
+ // Don't crash (QTBUG-53794)
+ QJSEngine engine;
+ engine.evaluate("with (noContext) true");
+}
+
QTEST_MAIN(tst_QJSEngine)
#include "tst_qjsengine.moc"
--
1.9.3

View File

@ -0,0 +1,63 @@
From 2ac19881f92c94f4e9427bd9ff513210675f259e Mon Sep 17 00:00:00 2001
From: Ulf Hermann <ulf.hermann@qt.io>
Date: Wed, 8 Jun 2016 17:32:32 +0200
Subject: [PATCH 33/40] QML: Only release types if they aren't referenced
anymore
Just checking for references on m_compiledData is not enough. The
actual component can also be referenced. Thus it won't be deleted
on release(), but cannot be found in the type cache anymore.
Task-number: QTBUG-53761
Change-Id: I8567af8e75a078598e4fed31e4717134e1332278
Reviewed-by: Mitch Curtis <mitch.curtis@qt.io>
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
---
src/qml/qml/qqmltypeloader.cpp | 3 ++-
tests/auto/qml/qqmltypeloader/tst_qqmltypeloader.cpp | 15 ++++++++++++---
2 files changed, 14 insertions(+), 4 deletions(-)
diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp
index c684c86..01200fd 100644
--- a/src/qml/qml/qqmltypeloader.cpp
+++ b/src/qml/qml/qqmltypeloader.cpp
@@ -1961,7 +1961,8 @@ void QQmlTypeLoader::trimCache()
QList<TypeCache::Iterator> unneededTypes;
for (TypeCache::Iterator iter = m_typeCache.begin(), end = m_typeCache.end(); iter != end; ++iter) {
QQmlTypeData *typeData = iter.value();
- if (typeData->m_compiledData && typeData->m_compiledData->count() == 1) {
+ if (typeData->m_compiledData && typeData->count() == 1
+ && typeData->m_compiledData->count() == 1) {
// There are no live objects of this type
unneededTypes.append(iter);
}
diff --git a/tests/auto/qml/qqmltypeloader/tst_qqmltypeloader.cpp b/tests/auto/qml/qqmltypeloader/tst_qqmltypeloader.cpp
index 7045c7c..a1eaa05 100644
--- a/tests/auto/qml/qqmltypeloader/tst_qqmltypeloader.cpp
+++ b/tests/auto/qml/qqmltypeloader/tst_qqmltypeloader.cpp
@@ -86,10 +86,19 @@ void tst_QQMLTypeLoader::trimCache()
url.setQuery(QString::number(i));
QQmlTypeData *data = loader.getType(url);
- if (i % 5 == 0) // keep references to some of them so that they aren't trimmed
- data->compiledData()->addref();
+ // Run an event loop to receive the callback that release()es.
+ QTRY_COMPARE(data->count(), 2);
- data->release();
+ // keep references to some of them so that they aren't trimmed. References to either the
+ // QQmlTypeData or its compiledData() should prevent the trimming.
+ if (i % 10 == 0) {
+ // keep ref on data, don't add ref on data->compiledData()
+ } else if (i % 5 == 0) {
+ data->compiledData()->addref();
+ data->release();
+ } else {
+ data->release();
+ }
}
for (int i = 0; i < 256; ++i) {
--
1.9.3

View File

@ -23,7 +23,7 @@
Summary: Qt5 - QtDeclarative component
Name: qt5-%{qt_module}
Version: 5.6.1
Release: 4%{?prerelease:.%{prerelease}}%{?dist}
Release: 5%{?prerelease:.%{prerelease}}%{?dist}
# See LICENSE.GPL LICENSE.LGPL LGPL_EXCEPTION.txt, for details
License: LGPLv2 with exceptions or GPLv3 with exceptions
@ -40,6 +40,13 @@ Patch1: qtdeclarative-opensource-src-5.5.0-no_sse2.patch
Patch2: qtdeclarative-QQuickShaderEffectSource_deadlock.patch
## upstream patches
Patch7: 0007-Revert-Remove-this-piece-of-code.patch
Patch10: 0010-Fix-crash-for-unknown-QQmlListModel-roles-in-debug-b.patch
Patch11: 0011-Avoid-Canvas-crashes-with-qtquickcompiler.patch
Patch16: 0016-Fix-crash-with-SignalTransition.patch
Patch24: 0024-Revert-removal-of-Fixed-MouseArea-threshold-with-pre.patch
Patch27: 0027-Fix-crash-when-using-with-statement-with-an-expressi.patch
Patch33: 0033-QML-Only-release-types-if-they-aren-t-referenced-any.patch
## upstreamable patches
# use system double-conversation
@ -120,6 +127,14 @@ Requires: %{name}%{?_isa} = %{version}-%{release}
%endif
%patch2 -p1 -b .QQuickShaderEffectSource_deadlock
%patch7 -p1 -b .0007
%patch10 -p1 -b .0010
%patch11 -p1 -b .0011
%patch16 -p1 -b .0016
%patch24 -p1 -b .0024
%patch27 -p1 -b .0027
%patch33 -p1 -b .0033
%if 0%{?system_doubleconv}
%patch200 -p1 -b .system_doubleconv
rm -rfv src/3rdparty/double-conversion
@ -273,6 +288,9 @@ make check -k -C %{_target_platform}/tests ||:
%changelog
* Thu Jun 16 2016 Rex Dieter <rdieter@fedoraproject.org> 5.6.1-5
- backport 5.6 branch fixes
* Wed Jun 15 2016 Rex Dieter <rdieter@fedoraproject.org> - 5.6.1-4
- drop pkgconfig-style Qt5 deps