diff options
author | Simon Hausmann <simon.hausmann@qt.io> | 2016-06-02 15:57:41 +0200 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@qt.io> | 2016-06-07 07:07:15 +0000 |
commit | 6d54a59bd725ba83e758236c5ff0fc7855109dac (patch) | |
tree | d49a7e5d4c4457bdaa7d80621e8211e091b21ea3 | |
parent | 6d63e3ba09954ce7b56b4b24432bd036e636b164 (diff) |
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>
-rw-r--r-- | src/qml/compiler/qv4codegen.cpp | 5 | ||||
-rw-r--r-- | 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 ea82d07e69..c14163a2f7 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 9a0865c0ac..8594aec8cd 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" |