fallthrough should not execute case expression (#1683)
authorAlex Lam S.L <alexlamsl@gmail.com>
Sun, 26 Mar 2017 08:52:38 +0000 (16:52 +0800)
committerGitHub <noreply@github.com>
Sun, 26 Mar 2017 08:52:38 +0000 (16:52 +0800)
- de-duplicate trailing cases only, avoid all potential side-effects
- enable switch statement fuzzing

fixes #1680

lib/compress.js
test/compress/switch.js
test/ufuzz.js

index 70bbb7f..8467f96 100644 (file)
@@ -2515,7 +2515,7 @@ merge(Compressor.prototype, {
             self.expression = best_of_expression(expression, self.expression);
         }
         if (compressor.option("dead_code")) {
-            var blocks = Object.create(null);
+            var prev_block;
             var decl = [];
             var body = [];
             var default_branch;
@@ -2542,31 +2542,21 @@ merge(Compressor.prototype, {
                         continue;
                     }
                 }
+                var case_side_effects = branch instanceof AST_Case && branch.expression.has_side_effects(compressor);
                 if (aborts(branch)) {
-                    var key = make_node(AST_BlockStatement, branch, branch).print_to_string();
-                    var block;
-                    if (!fallthrough && (block = blocks[key])) {
-                        block.body = [];
-                        body.splice(body.indexOf(block) + 1, 0, branch);
-                    } else {
-                        body.push(branch);
-                    }
+                    var block = make_node(AST_BlockStatement, branch, branch).print_to_string();
+                    if (!fallthrough && prev_block === block) body[body.length - 1].body = [];
+                    body.push(branch);
+                    prev_block = block;
                     fallthrough = false;
                 } else {
                     body.push(branch);
+                    prev_block = null;
                     fallthrough = true;
                 }
-                if (branch instanceof AST_Case && branch.expression.has_side_effects(compressor))
-                    blocks = Object.create(null);
-                if (!fallthrough) blocks[key] = branch;
             }
             for (; i < len && fallthrough; i++) {
                 branch = self.body[i];
-                if (branch instanceof AST_Case) {
-                    exact_match.body.push(make_node(AST_SimpleStatement, branch.expression, {
-                        body: branch.expression
-                    }));
-                }
                 exact_match.body = exact_match.body.concat(branch.body);
                 fallthrough = !aborts(exact_match);
             }
index 481257a..2025d91 100644 (file)
@@ -23,7 +23,6 @@ constant_switch_2: {
     }
     expect: {
         foo();
-        2;
         bar();
     }
 }
@@ -118,7 +117,6 @@ constant_switch_6: {
             x();
             if (foo) break OUT;
             y();
-            2;
             bar();
         }
     }
@@ -157,7 +155,6 @@ constant_switch_7: {
                 console.log(x);
             }
             y();
-            2;
             bar();
         }
     }
@@ -206,7 +203,6 @@ constant_switch_9: {
             x();
             for (;;) if (foo) break OUT;
             y();
-            2;
             bar();
             def();
         }
@@ -481,3 +477,79 @@ issue_1679: {
     }
     expect_stdout: true
 }
+
+issue_1680_1: {
+    options = {
+        dead_code: true,
+        evaluate: true,
+    }
+    input: {
+        function f(x) {
+            console.log(x);
+            return x + 1;
+        }
+        switch (2) {
+          case f(0):
+          case f(1):
+            f(2);
+          case 2:
+          case f(3):
+          case f(4):
+            f(5);
+        }
+    }
+    expect: {
+        function f(x) {
+            console.log(x);
+            return x + 1;
+        }
+        switch (2) {
+          case f(0):
+          case f(1):
+            f(2);
+          case 2:
+            f(5);
+        }
+    }
+    expect_stdout: [
+        "0",
+        "1",
+        "2",
+        "5",
+    ]
+}
+
+issue_1680_2: {
+    options = {
+        dead_code: true,
+    }
+    input: {
+        var a = 100, b = 10;
+        switch (b) {
+          case a--:
+            break;
+          case b:
+            var c;
+            break;
+          case a:
+            break;
+          case a--:
+            break;
+        }
+        console.log(a, b);
+    }
+    expect: {
+        var a = 100, b = 10;
+        switch (b) {
+          case a--:
+            break;
+          case b:
+            var c;
+            break;
+          case a:
+          case a--:
+        }
+        console.log(a, b);
+    }
+    expect_stdout: true
+}
index c56c622..4923625 100644 (file)
@@ -201,7 +201,6 @@ function createStatement(recurmax, canThrow, canBreak, canContinue) {
     case 6:
       return createExpression(recurmax) + ';';
     case 7:
-      return ';'; // TODO: disabled until some switch issues are resolved
       // note: case args are actual expressions
       // note: default does not _need_ to be last
       return 'switch (' + createExpression(recurmax) + ') { ' + createSwitchParts(recurmax, 4) + '}';