diff options
author | Sami Shalayel <[email protected]> | 2025-03-26 15:23:42 +0100 |
---|---|---|
committer | Sami Shalayel <[email protected]> | 2025-04-25 14:32:03 +0200 |
commit | f8e3ad0b097de4efa7e838ac6d0ae41b133e5822 (patch) | |
tree | a6c432c5dbbe7dc4d797c0066c2d6555a3a911c3 /tests | |
parent | c93c7ae3548489e866d1a2115c51012597a180a5 (diff) |
qmllint: warn about unreachable code
The compiler is very polite and does not tell the user about its useless
code. Codegen::statementList(StatementList *ast) silently discards
unreachable statements during byte code generation.
Warn the user that their code is unreachable. Don't warn about
function definitions because these ones are "hoisted" up,
which means that their definition is supposed to be pushed up, so that
they can be used even if they are behind a "return" or "throw"
statement.
Don't use the qqmljsbasicblock analysis for that, it reports too many
"false positives" where the compiler generates dead code that can't be
fixed by the user.
Task-number: QTBUG-129307
Change-Id: Ia26e8af1adf4e63b26dcaa7fb10be73b7eb084d7
Reviewed-by: Olivier De Cannière <[email protected]>
Diffstat (limited to 'tests')
-rw-r--r-- | tests/auto/qml/qmllint/tst_qmllint.cpp | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/tests/auto/qml/qmllint/tst_qmllint.cpp b/tests/auto/qml/qmllint/tst_qmllint.cpp index 0bf28ef52f..e2482686bb 100644 --- a/tests/auto/qml/qmllint/tst_qmllint.cpp +++ b/tests/auto/qml/qmllint/tst_qmllint.cpp @@ -1548,6 +1548,36 @@ void TestQmllint::dirtyJsSnippet_data() } << options; } + + QTest::newRow("codeAfterReturn") + << u"return 1; return 2;"_s << Result{ { { "Unreachable code"_L1, 1, 11 } } } + << defaultOptions; + + QTest::newRow("codeAfterBreak") + << u"for (;;) { break; return 1;}"_s << Result{ { { "Unreachable code"_L1, 1, 19 } } } + << defaultOptions; + QTest::newRow("codeAfterContinue") + << u"for (;;) { continue; return 1;}"_s + << Result{ { { "Unreachable code"_L1, 1, 22 } } } << defaultOptions; + QTest::newRow("codeAfterThrow") + << u"for (;;) { throw 1; return 1;}"_s << Result{ { { "Unreachable code"_L1, 1, 21 } } } + << defaultOptions; + + QTest::newRow("functionAfterThrow") + << u"throw 1; function f() {}; let x = 1; function g() {}; let y = 1;"_s + << Result{ { + { "Unreachable code"_L1, 1, 27 }, + { "Unreachable code"_L1, 1, 55 }, + } } + << defaultOptions; + + QTest::newRow("functionAfterThrow2") + << u"throw 1; if (x) { function f() {}; } let x = 1; if (x) { function g() {};} let y = 1;"_s + << Result{ { + { "Unreachable code"_L1, 1, 38 }, + { "Unreachable code"_L1, 1, 76 }, + } } + << defaultOptions; } void TestQmllint::dirtyJsSnippet() @@ -1594,6 +1624,15 @@ void TestQmllint::cleanJsSnippet_data() "// qmllint enable var-used-before-declaration\n" "let x = 3;"_s << defaultOptions; + + QTest::newRow("codeAfterReturn") << u"if (x) return 1; return 2;"_s << defaultOptions; + QTest::newRow("codeAfterReturn2") + << u"switch (1) { case 1: break; default: return 4;} return 3;"_s << defaultOptions; + QTest::newRow("codeAfterBreak") << u"for (;;) { if (x) break; return 1;}"_s << defaultOptions; + QTest::newRow("codeAfterContinue") + << u"for (;;) { if (x) continue; return 1;}"_s << defaultOptions; + QTest::newRow("codeAfterThrow") << u"for (;;) { if (x) throw 1; return 1;}"_s << defaultOptions; + QTest::newRow("functionAfterThrow") << u"throw 1; function f() {}"_s << defaultOptions; } void TestQmllint::cleanJsSnippet() |