aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/qml/compiler/qv4codegen.cpp7
-rw-r--r--tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp24
2 files changed, 28 insertions, 3 deletions
diff --git a/src/qml/compiler/qv4codegen.cpp b/src/qml/compiler/qv4codegen.cpp
index 27aecdd3ed..02274ca793 100644
--- a/src/qml/compiler/qv4codegen.cpp
+++ b/src/qml/compiler/qv4codegen.cpp
@@ -2448,7 +2448,8 @@ bool Codegen::visit(SwitchStatement *ast)
IR::BasicBlock *switchend = _function->newBasicBlock(exceptionHandler());
if (ast->block) {
- Result lhs = expression(ast->expression);
+ int lhs = _block->newTemp();
+ move(_block->TEMP(lhs), *expression(ast->expression));
IR::BasicBlock *switchcond = _function->newBasicBlock(exceptionHandler());
_block->JUMP(switchcond);
IR::BasicBlock *previousBlock = 0;
@@ -2510,7 +2511,7 @@ bool Codegen::visit(SwitchStatement *ast)
Result rhs = expression(clause->expression);
IR::BasicBlock *iftrue = blockMap[clause];
IR::BasicBlock *iffalse = _function->newBasicBlock(exceptionHandler());
- setLocation(cjump(binop(IR::OpStrictEqual, *lhs, *rhs), iftrue, iffalse), clause->caseToken);
+ setLocation(cjump(binop(IR::OpStrictEqual, _block->TEMP(lhs), *rhs), iftrue, iffalse), clause->caseToken);
_block = iffalse;
}
@@ -2519,7 +2520,7 @@ bool Codegen::visit(SwitchStatement *ast)
Result rhs = expression(clause->expression);
IR::BasicBlock *iftrue = blockMap[clause];
IR::BasicBlock *iffalse = _function->newBasicBlock(exceptionHandler());
- setLocation(cjump(binop(IR::OpStrictEqual, *lhs, *rhs), iftrue, iffalse), clause->caseToken);
+ setLocation(cjump(binop(IR::OpStrictEqual, _block->TEMP(lhs), *rhs), iftrue, iffalse), clause->caseToken);
_block = iffalse;
}
diff --git a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
index 722fd19af6..def04765a0 100644
--- a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
+++ b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
@@ -325,6 +325,7 @@ private slots:
void qtbug_39520();
void readUnregisteredQObjectProperty();
void writeUnregisteredQObjectProperty();
+ void switchExpression();
private:
// static void propertyVarWeakRefCallback(v8::Persistent<v8::Value> object, void* parameter);
@@ -7843,6 +7844,29 @@ void tst_qqmlecmascript::writeUnregisteredQObjectProperty()
QCOMPARE(root->property("container").value<ObjectContainer*>()->mSetterCalled, true);
}
+void tst_qqmlecmascript::switchExpression()
+{
+ // verify that we evaluate the expression inside switch() exactly once
+ QJSEngine engine;
+ QJSValue v = engine.evaluate(QString::fromLatin1(
+ "var num = 0\n"
+ "var x = 0\n"
+ "function f() { ++num; return (Math.random() > 0.5) ? 0 : 1; }\n"
+ "for (var i = 0; i < 1000; ++i) {\n"
+ " switch (f()) {\n"
+ " case 0:\n"
+ " case 1:\n"
+ " break;\n"
+ " default:\n"
+ " ++x;\n"
+ " }\n"
+ "}\n"
+ "(x == 0 && num == 1000) ? true : false\n"
+ ));
+ QVERIFY(!v.isError());
+ QCOMPARE(v.toBool(), true);
+}
+
QTEST_MAIN(tst_qqmlecmascript)
#include "tst_qqmlecmascript.moc"