diff options
author | Simon Hausmann <simon.hausmann@qt.io> | 2016-10-22 02:09:46 +0200 |
---|---|---|
committer | Erik Verbruggen <erik.verbruggen@qt.io> | 2016-10-25 08:48:52 +0000 |
commit | 708bb28c98721e83f8b5c12a2e0653834a68de23 (patch) | |
tree | 93dc0ca3f5860d8b9d8df8126a70f51d36f9ebcc | |
parent | ebff8e53c7c6c4fcbc7fc7e33709b64ec124e119 (diff) |
Fix crash when loop peeling and basic block merging
When trying to merge the second (original) loop header block of a peeled
loop, we would end up with dangling references to that block from the
loop body blocks. There's no trivial way to find all these quickly from
the header, so for now don't merge these blocks into the predecessor.
Change-Id: I2b5e39c5596ffd8c21ca9871af3a8150a019f2a8
Reviewed-by: Erik Verbruggen <erik.verbruggen@qt.io>
-rw-r--r-- | src/qml/compiler/qv4ssa.cpp | 4 | ||||
-rw-r--r-- | tests/auto/qml/qjsengine/tst_qjsengine.cpp | 18 |
2 files changed, 22 insertions, 0 deletions
diff --git a/src/qml/compiler/qv4ssa.cpp b/src/qml/compiler/qv4ssa.cpp index e4eaeaa3f6..4111cc77db 100644 --- a/src/qml/compiler/qv4ssa.cpp +++ b/src/qml/compiler/qv4ssa.cpp @@ -5075,6 +5075,10 @@ void mergeBasicBlocks(IR::Function *function, DefUses *du, DominatorTree *dt) BasicBlock *successor = bb->out.first(); if (successor->in.size() != 1) continue; // more than one incoming edge + // Loop header? No efficient way to update the other blocks that refer to this as containing group, + // so don't do merging yet. + if (successor->isGroupStart()) continue; + // Ok, we can merge the two basic blocks. if (DebugBlockMerging) { qDebug("Merging L%d into L%d", successor->index(), bb->index()); diff --git a/tests/auto/qml/qjsengine/tst_qjsengine.cpp b/tests/auto/qml/qjsengine/tst_qjsengine.cpp index d95d4ed59e..c20f0888d8 100644 --- a/tests/auto/qml/qjsengine/tst_qjsengine.cpp +++ b/tests/auto/qml/qjsengine/tst_qjsengine.cpp @@ -194,6 +194,8 @@ private slots: void withNoContext(); void holeInPropertyData(); + void basicBlockMergeAfterLoopPeeling(); + signals: void testSignal(); }; @@ -4044,6 +4046,22 @@ void tst_QJSEngine::holeInPropertyData() QVERIFY(ok.toBool()); } +void tst_QJSEngine::basicBlockMergeAfterLoopPeeling() +{ + QJSEngine engine; + QJSValue ok = engine.evaluate( + "function crashMe() {\n" + " var seen = false;\n" + " while (globalVar) {\n" + " if (seen)\n" + " return;\n" + " seen = true;\n" + " }\n" + "}\n"); + QVERIFY(!ok.isCallable()); + +} + QTEST_MAIN(tst_QJSEngine) #include "tst_qjsengine.moc" |