reset argument value within loop after `inline` (#2699)
authorAlex Lam S.L <alexlamsl@gmail.com>
Mon, 1 Jan 2018 17:24:53 +0000 (01:24 +0800)
committerGitHub <noreply@github.com>
Mon, 1 Jan 2018 17:24:53 +0000 (01:24 +0800)
lib/compress.js
test/compress/functions.js

index 73cc9d7..203c144 100644 (file)
@@ -3991,7 +3991,7 @@ merge(Compressor.prototype, {
             }
         }
         if (is_func) {
-            var def, value, scope, level = -1;
+            var def, value, scope, in_loop, level = -1;
             if (compressor.option("inline")
                 && !fn.uses_arguments
                 && !fn.uses_eval
@@ -4038,13 +4038,13 @@ merge(Compressor.prototype, {
         return self;
 
         function can_flatten_args(fn) {
-            var catches = Object.create(null), defs;
+            var catches = Object.create(null);
             do {
                 scope = compressor.parent(++level);
                 if (scope instanceof AST_Catch) {
                     catches[scope.argname.name] = true;
                 } else if (scope instanceof AST_IterationStatement) {
-                    defs = [];
+                    in_loop = [];
                 } else if (scope instanceof AST_SymbolRef) {
                     if (scope.fixed_value() instanceof AST_Scope) return false;
                 }
@@ -4059,9 +4059,9 @@ merge(Compressor.prototype, {
                     || scope.var_names()[arg.name]) {
                     return false;
                 }
-                if (defs) defs.push(arg.definition());
+                if (in_loop) in_loop.push(arg.definition());
             }
-            return !defs || defs.length == 0 || !is_reachable(stat, defs);
+            return !in_loop || in_loop.length == 0 || !is_reachable(stat, in_loop);
         }
 
         function flatten_args(fn) {
@@ -4087,6 +4087,7 @@ merge(Compressor.prototype, {
                     }));
                     var sym = make_node(AST_SymbolRef, name, name);
                     def.references.push(sym);
+                    if (!value && in_loop) value = make_node(AST_Undefined, self);
                     if (value) expressions.unshift(make_node(AST_Assign, self, {
                         operator: "=",
                         left: sym,
index 0e37b78..7acb7fd 100644 (file)
@@ -1671,3 +1671,26 @@ duplicate_argnames: {
     }
     expect_stdout: "PASS"
 }
+
+loop_init_arg: {
+    options = {
+        inline: true,
+        side_effects: true,
+        toplevel: true,
+    }
+    input: {
+        var a = "PASS";
+        for (var k in "12") (function (b) {
+            (b >>= 1) && (a = "FAIL"), b = 2;
+        })();
+        console.log(a);
+    }
+    expect: {
+        var a = "PASS";
+        for (var k in "12")
+            b = void 0, (b >>= 1) && (a = "FAIL"), b = 2;
+        var b;
+        console.log(a);
+    }
+    expect_stdout: "PASS"
+}