fix corner case in `side_effects` (#4326)
authorAlex Lam S.L <alexlamsl@gmail.com>
Sun, 29 Nov 2020 02:05:48 +0000 (02:05 +0000)
committerGitHub <noreply@github.com>
Sun, 29 Nov 2020 02:05:48 +0000 (10:05 +0800)
fixes #4325

lib/compress.js
test/compress/functions.js
test/compress/keep_fargs.js
test/compress/loops.js
test/compress/side_effects.js

index 708b9df..7434a20 100644 (file)
@@ -5592,20 +5592,10 @@ merge(Compressor.prototype, {
             } else if (node instanceof AST_ForIn) {
                 if (!drop_vars || !compressor.option("loops")) return;
                 if (!is_empty(node.body)) return;
-                var sym = node.init;
-                if (sym instanceof AST_Definitions) {
-                    sym = sym.definitions[0].name;
-                } else while (sym instanceof AST_PropAccess) {
-                    sym = sym.expression.tail_node();
-                }
-                if (sym instanceof AST_Destructured) return;
+                var sym = get_init_symbol(node);
+                if (!sym) return;
                 var def = sym.definition();
-                if (!def) return;
                 if (def.id in in_use_ids) return;
-                if (def.scope !== self) {
-                    var d = self.find_variable(sym);
-                    if ((d && d.redefined() || d) === def) return;
-                }
                 log(sym, "Dropping unused loop variable {name}");
                 if (for_ins[def.id] === node) delete for_ins[def.id];
                 var body = [];
@@ -5705,6 +5695,16 @@ merge(Compressor.prototype, {
             return rhs.right;
         }
 
+        function get_init_symbol(for_in) {
+            var init = for_in.init;
+            if (init instanceof AST_Definitions) {
+                init = init.definitions[0].name;
+                return init instanceof AST_SymbolDeclaration && init;
+            }
+            while (init instanceof AST_PropAccess) init = init.expression.tail_node();
+            if (init instanceof AST_SymbolRef) return init;
+        }
+
         function scan_ref_scoped(node, descend, init) {
             if (node instanceof AST_Assign && node.left instanceof AST_SymbolRef) {
                 var def = node.left.definition();
@@ -5748,8 +5748,14 @@ merge(Compressor.prototype, {
                 }
                 if (!drop_vars || !compressor.option("loops")) return;
                 if (!is_empty(node.body)) return;
-                if (node.init instanceof AST_Destructured) return;
                 if (node.init.has_side_effects(compressor)) return;
+                var sym = get_init_symbol(node);
+                if (!sym) return;
+                var def = sym.definition();
+                if (def.scope !== self) {
+                    var d = self.find_variable(sym);
+                    if ((d && d.redefined() || d) === def) return;
+                }
                 node.object.walk(tw);
                 return true;
             }
@@ -6259,6 +6265,7 @@ merge(Compressor.prototype, {
                 });
                 // always shallow clone to ensure stripping of negated IIFEs
                 self = self.clone();
+                self.expression = exp.clone();
             }
             if (self instanceof AST_New) {
                 var fn = exp;
index e06596b..49bbfac 100644 (file)
@@ -3322,9 +3322,7 @@ issue_3506_1: {
     }
     expect: {
         var a = "FAIL";
-        !function(b) {
-            b && (a = "PASS");
-        }(a);
+        a && (a = "PASS");
         console.log(a);
     }
     expect_stdout: "PASS"
index e173708..7141a41 100644 (file)
@@ -525,7 +525,7 @@ issue_2506: {
         function f0(bar) {
             (function() {
                 (function() {
-                    if (false <= 0/0 & this >> 1 >= 0)
+                    if (false <= NaN & this >> 1 >= 0)
                         c++;
                 })(c++);
             })();
index 6915082..c16fa5b 100644 (file)
@@ -1052,6 +1052,7 @@ issue_4084: {
     options = {
         keep_fargs: "strict",
         loops: true,
+        passes: 2,
         reduce_vars: true,
         unused: true,
     }
index 3c53dd2..0654a4c 100644 (file)
@@ -433,3 +433,40 @@ trim_new: {
     }
     expect_stdout: "PASS"
 }
+
+issue_4325: {
+    options = {
+        keep_fargs: "strict",
+        passes: 2,
+        pure_getters: "strict",
+        reduce_vars: true,
+        side_effects: true,
+        unused: true,
+    }
+    input: {
+        (function f() {
+            (function(b, c) {
+                try {
+                    c.p = 0;
+                } catch (e) {
+                    console.log("PASS");
+                    return b;
+                }
+                c;
+            })(f++);
+        })();
+    }
+    expect: {
+        (function() {
+            (function() {
+                try {
+                    (void 0).p = 0;
+                } catch (e) {
+                    console.log("PASS");
+                    return;
+                }
+            })();
+        })();
+    }
+    expect_stdout: "PASS"
+}