fix corner case in `merge_vars` (#4127)
authorAlex Lam S.L <alexlamsl@gmail.com>
Sat, 19 Sep 2020 11:56:21 +0000 (12:56 +0100)
committerGitHub <noreply@github.com>
Sat, 19 Sep 2020 11:56:21 +0000 (19:56 +0800)
fixes #4126

lib/compress.js
test/compress/merge_vars.js

index c30e4b8..0f9fa6b 100644 (file)
@@ -4436,14 +4436,15 @@ merge(Compressor.prototype, {
             }
             if (node instanceof AST_Try) {
                 push();
+                segment.block = node;
                 walk_body(node, tw);
-                pop();
                 if (node.bcatch) {
                     references[node.bcatch.argname.definition().id] = false;
+                    pop();
                     push();
                     walk_body(node.bcatch, tw);
-                    pop();
                 }
+                pop();
                 if (node.bfinally) node.bfinally.walk(tw);
                 return true;
             }
@@ -4475,7 +4476,8 @@ merge(Compressor.prototype, {
             var head = first.pop();
             var def = head.definition;
             if (!(def.id in prev)) continue;
-            if (!references[def.id]) continue;
+            var head_refs = references[def.id];
+            if (!head_refs) continue;
             while (def.id in merged) def = merged[def.id];
             var skipped = [];
             do {
@@ -4483,13 +4485,14 @@ merge(Compressor.prototype, {
                 if (!tail) continue;
                 if (tail.index > head.index) continue;
                 var id = tail.definition.id;
-                if (!references[id]) continue;
-                if (!mergeable()) {
+                var tail_refs = references[id];
+                if (!tail_refs) continue;
+                if (!mergeable(head_refs, tail_refs)) {
                     skipped.unshift(tail);
                     continue;
                 }
                 var orig = [], refs = [];
-                references[id].forEach(function(sym) {
+                tail_refs.forEach(function(sym) {
                     sym.thedef = def;
                     sym.name = def.name;
                     if (sym instanceof AST_SymbolRef) {
@@ -4556,9 +4559,7 @@ merge(Compressor.prototype, {
             return base === segment || base.isPrototypeOf(segment);
         }
 
-        function mergeable() {
-            var head = references[def.id];
-            var tail = references[id];
+        function mergeable(head, tail) {
             if (head.start.block !== tail.start.block) return false;
             return must_visit(head.start, head.end) || must_visit(head.start, tail.start);
         }
index f1b0e70..0641be7 100644 (file)
@@ -2594,3 +2594,71 @@ cross_branch_2b_15: {
         "bar",
     ]
 }
+
+issue_4126_1: {
+    options = {
+        merge_vars: true,
+    }
+    input: {
+        function f(a) {
+            try {
+                console.log("PASS");
+            } catch (e) {
+                var b = a;
+            } finally {
+                var c = b;
+            }
+            console.log(c);
+        }
+        f("FAIL");
+    }
+    expect: {
+        function f(a) {
+            try {
+                console.log("PASS");
+            } catch (e) {
+                var c = a;
+            } finally {
+                var c = c;
+            }
+            console.log(c);
+        }
+        f("FAIL");
+    }
+    expect_stdout: [
+        "PASS",
+        "undefined",
+    ]
+}
+
+issue_4126_2: {
+    options = {
+        inline: true,
+        merge_vars: true,
+        side_effects: true,
+        toplevel: true,
+    }
+    input: {
+        try {
+            var a = function() {
+                var b = 0;
+                function f() {
+                    b;
+                }
+                THROW(b);
+            }();
+        } catch (e) {
+            console.log(a);
+        }
+    }
+    expect: {
+        try {
+            var a = (b = 0, void THROW(b));
+        } catch (e) {
+            console.log(a);
+        }
+        function f() {}
+        var b;
+    }
+    expect_stdout: "undefined"
+}