fix corner case in `merge_vars` (#4760)
authorAlex Lam S.L <alexlamsl@gmail.com>
Wed, 10 Mar 2021 15:44:49 +0000 (15:44 +0000)
committerGitHub <noreply@github.com>
Wed, 10 Mar 2021 15:44:49 +0000 (23:44 +0800)
fixes #4759

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

index e207fed..d01ebbe 100644 (file)
@@ -5271,7 +5271,7 @@ merge(Compressor.prototype, {
     var NO_MERGE = makePredicate("arguments await yield");
     AST_Scope.DEFMETHOD("merge_variables", function(compressor) {
         if (!compressor.option("merge_vars")) return;
-        var self = this, segment = {}, root;
+        var in_try, root, segment = {}, self = this;
         var first = [], last = [], index = 0;
         var declarations = new Dictionary();
         var references = Object.create(null);
@@ -5476,10 +5476,11 @@ merge(Compressor.prototype, {
                 return true;
             }
             if (node instanceof AST_Try) {
-                push();
-                segment.block = node;
+                var save_try = in_try;
+                in_try = node;
+                var save = segment;
                 walk_body(node, tw);
-                pop();
+                segment = save;
                 if (node.bcatch) {
                     if (node.bcatch.argname) node.bcatch.argname.mark_symbol(function(node) {
                         if (node instanceof AST_SymbolCatch) {
@@ -5488,11 +5489,16 @@ merge(Compressor.prototype, {
                             if (def = def.redefined()) references[def.id] = false;
                         }
                     }, tw);
-                    push();
-                    if (node.bfinally) segment.block = node.bcatch;
-                    walk_body(node.bcatch, tw);
-                    pop();
+                    if (node.bfinally || (in_try = save_try)) {
+                        walk_body(node.bcatch, tw);
+                    } else {
+                        push();
+                        walk_body(node.bcatch, tw);
+                        pop();
+                    }
                 }
+                in_try = save_try;
+                segment = save;
                 if (node.bfinally) node.bfinally.walk(tw);
                 return true;
             }
@@ -5599,6 +5605,7 @@ merge(Compressor.prototype, {
         }
 
         function mark(sym, read) {
+            if (in_try) push();
             var def = sym.definition(), ldef;
             if (def.id in references) {
                 var refs = references[def.id];
index c45f835..a26c0dd 100644 (file)
@@ -2620,9 +2620,9 @@ issue_4126_1: {
             try {
                 console.log("PASS");
             } catch (e) {
-                var b = a;
+                var c = a;
             } finally {
-                var c = b;
+                var c = c;
             }
             console.log(c);
         }
@@ -3239,3 +3239,45 @@ issue_4653: {
         "0",
     ]
 }
+
+issue_4759: {
+    options = {
+        merge_vars: true,
+        toplevel: true,
+    }
+    input: {
+        var i = 2, a = 1, b, c, d;
+        while (i--) {
+            try {
+                if (1 != b) {
+                    d = [];
+                    null.p;
+                    c = d;
+                } else {
+                    b = 0;
+                    a = c;
+                }
+            } catch (e) {}
+            b = a;
+        }
+        console.log(a);
+    }
+    expect: {
+        var i = 2, a = 1, b, c, d;
+        while (i--) {
+            try {
+                if (1 != b) {
+                    d = [];
+                    null.p;
+                    c = d;
+                } else {
+                    b = 0;
+                    a = c;
+                }
+            } catch (e) {}
+            b = a;
+        }
+        console.log(a);
+    }
+    expect_stdout: "undefined"
+}