From 8d0d1b11e381130dec12f46b959c3107c3f47160 Mon Sep 17 00:00:00 2001 From: Erik Verbruggen Date: Thu, 6 Apr 2017 15:42:51 +0200 Subject: V4: Fix issues with very small loops Loops consisting of just a single basic block (e.g. a do-while loop with no nested loops or if statements) have a back-edge to themselves. There were 2 problems: - loop detection would create LoopInfo for any loop header referred to by blocks inside the loop (and a 1 block loop doesn't have body blocks), nor would it mark the loop header as such - when splitting critical edges, the newly inserted block would not be marked as part of the loop This is a problem specifically for 1 block loops: the block ends with a CJUMP, so the back-edge is a critical edge. So the new block inserted by edge splitting wouldn't be marked as belonging to the loop. The end result was that the life-time intervals for temporaries that are defined before the loop, but that are used inside the loop, and not after the loop, would have their life-time ended before the loop ends (instead of spanning the whole loop, *including* the back-edge). This in turns could lead to the stack/register allocator re-using the storage for that temporary, resulting in strange things happening. Task-number: QTBUG-59012 Change-Id: Ic946c73913711272efea2151cb85350412ca2fde Reviewed-by: Simon Hausmann --- tests/auto/qml/qqmlecmascript/data/qtbug_59012.qml | 14 ++++++++++++++ tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp | 10 ++++++++++ 2 files changed, 24 insertions(+) create mode 100644 tests/auto/qml/qqmlecmascript/data/qtbug_59012.qml (limited to 'tests') diff --git a/tests/auto/qml/qqmlecmascript/data/qtbug_59012.qml b/tests/auto/qml/qqmlecmascript/data/qtbug_59012.qml new file mode 100644 index 0000000000..5283614435 --- /dev/null +++ b/tests/auto/qml/qqmlecmascript/data/qtbug_59012.qml @@ -0,0 +1,14 @@ +import QtQuick 2.0 + +QtObject { + Component.onCompleted: { + var pieces = [[4,21],[6,22],[8,23],[12,24],[10,25],[8,26],[6,27],[4,28],[2,31],[2,32],[2,33],[2,35],[2,36],[2,37],[2,38],[2,54]] + var i = pieces.length; + var king = 10 + var val + do { + var p = pieces[--i]; + val = p[0] + } while (val !== king); + } +} diff --git a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp index 20f7940e9d..068881affb 100644 --- a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp +++ b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp @@ -331,6 +331,7 @@ private slots: void qtbug_54589(); void qtbug_54687(); void stringify_qtbug_50592(); + void singleBlockLoops(); private: // static void propertyVarWeakRefCallback(v8::Persistent object, void* parameter); @@ -8119,6 +8120,15 @@ void tst_qqmlecmascript::stringify_qtbug_50592() QCOMPARE(obj->property("source").toString(), QString::fromLatin1("http://example.org/some_nonexistant_image.png")); } +void tst_qqmlecmascript::singleBlockLoops() +{ + QQmlComponent component(&engine, testFileUrl("qtbug_59012.qml")); + + QScopedPointer obj(component.create()); + QVERIFY(obj != 0); + QVERIFY(!component.isError()); +} + QTEST_MAIN(tst_qqmlecmascript) #include "tst_qqmlecmascript.moc" -- cgit v1.2.3