Fix crash when using continue in switch inside loop
authorSimon Hausmann <simon.hausmann@digia.com>
Wed, 23 Jan 2013 08:42:46 +0000 (09:42 +0100)
committerLars Knoll <lars.knoll@digia.com>
Wed, 23 Jan 2013 08:56:04 +0000 (09:56 +0100)
Statements like switch() call enterLoop() with a null continue block.
However it is permitted to use continue inside a case in switch, and
that should then continue in the next outter loop that supports it.

Change-Id: I723d2dad3123a2a658964d541522c7961f578dbf
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
qv4codegen.cpp
tests/switch.2.js [new file with mode: 0644]

index 41d1d6b..7948ff1 100644 (file)
@@ -1988,7 +1988,12 @@ bool Codegen::visit(ContinueStatement *ast)
     unwindException(_loop->tryCleanup);
 
     if (ast->label.isEmpty()) {
-        _block->JUMP(_loop->continueBlock);
+        for (Loop *loop = _loop; loop; loop = loop->parent) {
+            if (loop->continueBlock) {
+                _block->JUMP(loop->continueBlock);
+                return false;
+            }
+        }
     } else {
         for (Loop *loop = _loop; loop; loop = loop->parent) {
             if (loop->labelledStatement && loop->labelledStatement->label == ast->label) {
@@ -1999,8 +2004,8 @@ bool Codegen::visit(ContinueStatement *ast)
                 return false;
             }
         }
-        throwSyntaxError(ast->lastSourceLocation(), QCoreApplication::translate("qv4codegen", "Undefined label '%1'").arg(ast->label.toString()));
     }
+    throwSyntaxError(ast->lastSourceLocation(), QCoreApplication::translate("qv4codegen", "Undefined label '%1'").arg(ast->label.toString()));
     return false;
 }
 
diff --git a/tests/switch.2.js b/tests/switch.2.js
new file mode 100644 (file)
index 0000000..60d59c1
--- /dev/null
@@ -0,0 +1,11 @@
+var i;
+for (i = 0; i < 2; ++i) {
+    switch ("a") {
+        case "a":
+            continue;
+        default:
+            break;
+    }
+}
+if (i != 2)
+    print("loop did not run often enough");