fix corner case in `loops` (#3635)
authorAlex Lam S.L <alexlamsl@gmail.com>
Tue, 10 Dec 2019 22:39:46 +0000 (06:39 +0800)
committerGitHub <noreply@github.com>
Tue, 10 Dec 2019 22:39:46 +0000 (06:39 +0800)
fixes #3634

lib/compress.js
test/compress/loops.js

index fb7e66d..3b40a5d 100644 (file)
@@ -4719,7 +4719,10 @@ merge(Compressor.prototype, {
 
     function if_break_in_loop(self, compressor) {
         var first = first_statement(self.body);
-        if (compressor.option("dead_code") && (breaks(first) || first instanceof AST_Exit)) {
+        if (compressor.option("dead_code")
+            && (first instanceof AST_Break
+                || first instanceof AST_Continue && external_target(first)
+                || first instanceof AST_Exit)) {
             var body = [];
             if (self.init instanceof AST_Statement) {
                 body.push(self.init);
@@ -4749,7 +4752,7 @@ merge(Compressor.prototype, {
         }
         if (first instanceof AST_If) {
             var ab = first_statement(first.body);
-            if (breaks(ab)) {
+            if (ab instanceof AST_Break && !external_target(ab)) {
                 if (self.condition) {
                     self.condition = make_node(AST_Binary, self.condition, {
                         left: self.condition,
@@ -4764,7 +4767,7 @@ merge(Compressor.prototype, {
                 return drop_it(body);
             }
             ab = first_statement(first.alternative);
-            if (breaks(ab)) {
+            if (ab instanceof AST_Break && !external_target(ab)) {
                 if (self.condition) {
                     self.condition = make_node(AST_Binary, self.condition, {
                         left: self.condition,
@@ -4789,11 +4792,6 @@ merge(Compressor.prototype, {
             return compressor.loopcontrol_target(node) !== compressor.self();
         }
 
-        function breaks(node) {
-            return node instanceof AST_Break
-                || node instanceof AST_Continue && external_target(node);
-        }
-
         function drop_it(rest) {
             if (self.body instanceof AST_BlockStatement) {
                 self.body = self.body.clone();
index 5f3b927..db0fbb9 100644 (file)
@@ -879,3 +879,51 @@ loop_return: {
     }
     expect_stdout: "foo 42"
 }
+
+issue_3634_1: {
+    options = {
+        loops: true,
+    }
+    input: {
+        var b = 0;
+        L: while (++b < 2)
+            while (1)
+                if (b) break L;
+        console.log(b);
+    }
+    expect: {
+        var b = 0;
+        L: for (;++b < 2;)
+            for (;1;)
+                if (b) break L;
+        console.log(b);
+    }
+    expect_stdout: "1"
+}
+
+issue_3634_2: {
+    options = {
+        loops: true,
+    }
+    input: {
+        var b = 0;
+        L: while (++b < 2)
+            while (1)
+                if (!b)
+                    continue L;
+                else
+                    break L;
+        console.log(b);
+    }
+    expect: {
+        var b = 0;
+        L: for (;++b < 2;)
+            for (;1;)
+                if (!b)
+                    continue L;
+                else
+                    break L;
+        console.log(b);
+    }
+    expect_stdout: "1"
+}