aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@qt.io>2016-10-22 02:09:46 +0200
committerErik Verbruggen <erik.verbruggen@qt.io>2016-10-25 08:48:52 +0000
commit708bb28c98721e83f8b5c12a2e0653834a68de23 (patch)
tree93dc0ca3f5860d8b9d8df8126a70f51d36f9ebcc
parentebff8e53c7c6c4fcbc7fc7e33709b64ec124e119 (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.cpp4
-rw-r--r--tests/auto/qml/qjsengine/tst_qjsengine.cpp18
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"