From 04fd3d90f8600bc8c6c5715abce06617110d88d6 Mon Sep 17 00:00:00 2001 From: "Alex Lam S.L" Date: Thu, 4 Jun 2020 21:06:43 +0100 Subject: fix corner cases in `assignments`, `reduce_vars` & `unused` (#3950) fixes #3949 fixes #3951 --- test/compress/assignment.js | 409 ------------------------------------ test/compress/assignments.js | 463 +++++++++++++++++++++++++++++++++++++++++ test/compress/collapse_vars.js | 1 + test/compress/drop-unused.js | 35 +++- test/compress/evaluate.js | 18 +- test/compress/join_vars.js | 4 +- test/compress/keep_fargs.js | 1 + test/compress/reduce_vars.js | 170 ++++++++++++++- test/compress/side_effects.js | 3 +- 9 files changed, 672 insertions(+), 432 deletions(-) delete mode 100644 test/compress/assignment.js create mode 100644 test/compress/assignments.js (limited to 'test/compress') diff --git a/test/compress/assignment.js b/test/compress/assignment.js deleted file mode 100644 index 2230272a..00000000 --- a/test/compress/assignment.js +++ /dev/null @@ -1,409 +0,0 @@ -op_equals_left_local_var: { - options = { - assignments: true, - evaluate: true, - } - input: { - var x; - - x = x + 3; - x = x - 3; - x = x / 3; - x = x * 3; - x = x >> 3; - x = x << 3; - x = x >>> 3; - x = x | 3; - x = x ^ 3; - x = x % 3; - x = x & 3; - - x = x + g(); - x = x - g(); - x = x / g(); - x = x * g(); - x = x >> g(); - x = x << g(); - x = x >>> g(); - x = x | g(); - x = x ^ g(); - x = x % g(); - x = x & g(); - } - expect: { - var x; - - x += 3; - x -= 3; - x /= 3; - x *= 3; - x >>= 3; - x <<= 3; - x >>>= 3; - x |= 3; - x ^= 3; - x %= 3; - x &= 3; - - x += g(); - x -= g(); - x /= g(); - x *= g(); - x >>= g(); - x <<= g(); - x >>>= g(); - x |= g(); - x ^= g(); - x %= g(); - x &= g(); - } -} - -op_equals_right_local_var: { - options = { - assignments: true, - evaluate: true, - } - input: { - var x; - - x = (x -= 2) ^ x; - - x = 3 + x; - x = 3 - x; - x = 3 / x; - x = 3 * x; - x = 3 >> x; - x = 3 << x; - x = 3 >>> x; - x = 3 | x; - x = 3 ^ x; - x = 3 % x; - x = 3 & x; - - x = g() + x; - x = g() - x; - x = g() / x; - x = g() * x; - x = g() >> x; - x = g() << x; - x = g() >>> x; - x = g() | x; - x = g() ^ x; - x = g() % x; - x = g() & x; - } - expect: { - var x; - - x = (x -= 2) ^ x; - - x = 3 + x; - x = 3 - x; - x = 3 / x; - x *= 3; - x = 3 >> x; - x = 3 << x; - x = 3 >>> x; - x |= 3; - x ^= 3; - x = 3 % x; - x &= 3; - - x = g() + x; - x = g() - x; - x = g() / x; - x = g() * x; - x = g() >> x; - x = g() << x; - x = g() >>> x; - x = g() | x; - x = g() ^ x; - x = g() % x; - x = g() & x; - } -} -op_equals_left_global_var: { - options = { - assignments: true, - evaluate: true, - } - input: { - x = x + 3; - x = x - 3; - x = x / 3; - x = x * 3; - x = x >> 3; - x = x << 3; - x = x >>> 3; - x = x | 3; - x = x ^ 3; - x = x % 3; - x = x & 3; - - x = x + g(); - x = x - g(); - x = x / g(); - x = x * g(); - x = x >> g(); - x = x << g(); - x = x >>> g(); - x = x | g(); - x = x ^ g(); - x = x % g(); - x = x & g(); - } - expect: { - x += 3; - x -= 3; - x /= 3; - x *= 3; - x >>= 3; - x <<= 3; - x >>>= 3; - x |= 3; - x ^= 3; - x %= 3; - x &= 3; - - x += g(); - x -= g(); - x /= g(); - x *= g(); - x >>= g(); - x <<= g(); - x >>>= g(); - x |= g(); - x ^= g(); - x %= g(); - x &= g(); - } -} - -op_equals_right_global_var: { - options = { - assignments: true, - evaluate: true, - } - input: { - x = (x -= 2) ^ x; - - x = 3 + x; - x = 3 - x; - x = 3 / x; - x = 3 * x; - x = 3 >> x; - x = 3 << x; - x = 3 >>> x; - x = 3 | x; - x = 3 ^ x; - x = 3 % x; - x = 3 & x; - - x = g() + x; - x = g() - x; - x = g() / x; - x = g() * x; - x = g() >> x; - x = g() << x; - x = g() >>> x; - x = g() | x; - x = g() ^ x; - x = g() % x; - x = g() & x; - } - expect: { - x = (x -= 2) ^ x; - - x = 3 + x; - x = 3 - x; - x = 3 / x; - x *= 3; - x = 3 >> x; - x = 3 << x; - x = 3 >>> x; - x |= 3; - x ^= 3; - x = 3 % x; - x &= 3; - - x = g() + x; - x = g() - x; - x = g() / x; - x = g() * x; - x = g() >> x; - x = g() << x; - x = g() >>> x; - x = g() | x; - x = g() ^ x; - x = g() % x; - x = g() & x; - } -} - -increment_decrement_1: { - options = { - assignments: true, - reduce_vars: true, - } - input: { - console.log(function(a) { - a += 1; - a -= 1; - return a; - }(42)); - } - expect: { - console.log(function(a){ - ++a; - --a; - return a; - }(42)); - } - expect_stdout: "42" -} - -increment_decrement_2: { - options = { - assignments: true, - passes: 2, - reduce_vars: true, - } - input: { - console.log(function(a) { - a = a + 1; - a = a - 1; - a += 1; - a -= 1; - return a; - }(42)); - } - expect: { - console.log(function(a){ - ++a; - --a; - ++a; - --a; - return a; - }(42)); - } - expect_stdout: "42" -} - -issue_3375_1: { - options = { - assignments: true, - reduce_vars: true, - } - input: { - function p(o) { - console.log(typeof o, o); - } - p(function(b) { - var a = b += 1; - --b; - return a; - }("object")); - } - expect: { - function p(o) { - console.log(typeof o, o); - } - p(function(b) { - var a = b += 1; - --b; - return a; - }("object")); - } - expect_stdout: "string object1" -} - -issue_3375_2: { - options = { - assignments: true, - reduce_vars: true, - } - input: { - function p(o) { - console.log(typeof o, o); - } - p(function(b) { - var a = b -= 1; - --b; - return a; - }("object")); - } - expect: { - function p(o) { - console.log(typeof o, o); - } - p(function(b) { - var a = --b; - --b; - return a; - }("object")); - } - expect_stdout: "number NaN" -} - -issue_3427: { - options = { - assignments: true, - sequences: true, - side_effects: true, - unused: true, - } - input: { - (function() { - var a; - a || (a = {}); - })(); - } - expect: {} -} - -issue_3429_1: { - options = { - assignments: true, - side_effects: true, - unused: true, - } - input: { - var a = "PASS"; - (function(b) { - b && (b = a = "FAIL"); - })(); - console.log(a); - } - expect: { - var a = "PASS"; - (function(b) { - b = b && (a = "FAIL"); - })(); - console.log(a); - } - expect_stdout: "PASS" -} - -issue_3429_2: { - options = { - assignments: true, - side_effects: true, - unused: true, - } - input: { - var a; - (function(b) { - b || (b = a = "FAIL"); - })(42); - console.log(a); - } - expect: { - var a; - (function(b) { - b = b || (a = "FAIL"); - })(42); - console.log(a); - } - expect_stdout: "undefined" -} diff --git a/test/compress/assignments.js b/test/compress/assignments.js new file mode 100644 index 00000000..0f87f9a0 --- /dev/null +++ b/test/compress/assignments.js @@ -0,0 +1,463 @@ +op_equals_left_local_var: { + options = { + assignments: true, + evaluate: true, + } + input: { + var x; + + x = x + 3; + x = x - 3; + x = x / 3; + x = x * 3; + x = x >> 3; + x = x << 3; + x = x >>> 3; + x = x | 3; + x = x ^ 3; + x = x % 3; + x = x & 3; + + x = x + g(); + x = x - g(); + x = x / g(); + x = x * g(); + x = x >> g(); + x = x << g(); + x = x >>> g(); + x = x | g(); + x = x ^ g(); + x = x % g(); + x = x & g(); + } + expect: { + var x; + + x += 3; + x -= 3; + x /= 3; + x *= 3; + x >>= 3; + x <<= 3; + x >>>= 3; + x |= 3; + x ^= 3; + x %= 3; + x &= 3; + + x += g(); + x -= g(); + x /= g(); + x *= g(); + x >>= g(); + x <<= g(); + x >>>= g(); + x |= g(); + x ^= g(); + x %= g(); + x &= g(); + } +} + +op_equals_right_local_var: { + options = { + assignments: true, + evaluate: true, + } + input: { + var x; + + x = (x -= 2) ^ x; + + x = 3 + x; + x = 3 - x; + x = 3 / x; + x = 3 * x; + x = 3 >> x; + x = 3 << x; + x = 3 >>> x; + x = 3 | x; + x = 3 ^ x; + x = 3 % x; + x = 3 & x; + + x = g() + x; + x = g() - x; + x = g() / x; + x = g() * x; + x = g() >> x; + x = g() << x; + x = g() >>> x; + x = g() | x; + x = g() ^ x; + x = g() % x; + x = g() & x; + } + expect: { + var x; + + x = (x -= 2) ^ x; + + x = 3 + x; + x = 3 - x; + x = 3 / x; + x *= 3; + x = 3 >> x; + x = 3 << x; + x = 3 >>> x; + x |= 3; + x ^= 3; + x = 3 % x; + x &= 3; + + x = g() + x; + x = g() - x; + x = g() / x; + x = g() * x; + x = g() >> x; + x = g() << x; + x = g() >>> x; + x = g() | x; + x = g() ^ x; + x = g() % x; + x = g() & x; + } +} +op_equals_left_global_var: { + options = { + assignments: true, + evaluate: true, + } + input: { + x = x + 3; + x = x - 3; + x = x / 3; + x = x * 3; + x = x >> 3; + x = x << 3; + x = x >>> 3; + x = x | 3; + x = x ^ 3; + x = x % 3; + x = x & 3; + + x = x + g(); + x = x - g(); + x = x / g(); + x = x * g(); + x = x >> g(); + x = x << g(); + x = x >>> g(); + x = x | g(); + x = x ^ g(); + x = x % g(); + x = x & g(); + } + expect: { + x += 3; + x -= 3; + x /= 3; + x *= 3; + x >>= 3; + x <<= 3; + x >>>= 3; + x |= 3; + x ^= 3; + x %= 3; + x &= 3; + + x += g(); + x -= g(); + x /= g(); + x *= g(); + x >>= g(); + x <<= g(); + x >>>= g(); + x |= g(); + x ^= g(); + x %= g(); + x &= g(); + } +} + +op_equals_right_global_var: { + options = { + assignments: true, + evaluate: true, + } + input: { + x = (x -= 2) ^ x; + + x = 3 + x; + x = 3 - x; + x = 3 / x; + x = 3 * x; + x = 3 >> x; + x = 3 << x; + x = 3 >>> x; + x = 3 | x; + x = 3 ^ x; + x = 3 % x; + x = 3 & x; + + x = g() + x; + x = g() - x; + x = g() / x; + x = g() * x; + x = g() >> x; + x = g() << x; + x = g() >>> x; + x = g() | x; + x = g() ^ x; + x = g() % x; + x = g() & x; + } + expect: { + x = (x -= 2) ^ x; + + x = 3 + x; + x = 3 - x; + x = 3 / x; + x *= 3; + x = 3 >> x; + x = 3 << x; + x = 3 >>> x; + x |= 3; + x ^= 3; + x = 3 % x; + x &= 3; + + x = g() + x; + x = g() - x; + x = g() / x; + x = g() * x; + x = g() >> x; + x = g() << x; + x = g() >>> x; + x = g() | x; + x = g() ^ x; + x = g() % x; + x = g() & x; + } +} + +increment_decrement_1: { + options = { + assignments: true, + reduce_vars: true, + } + input: { + console.log(function(a) { + a += 1; + a -= 1; + return a; + }(42)); + } + expect: { + console.log(function(a){ + ++a; + --a; + return a; + }(42)); + } + expect_stdout: "42" +} + +increment_decrement_2: { + options = { + assignments: true, + passes: 2, + reduce_vars: true, + } + input: { + console.log(function(a) { + a = a + 1; + a = a - 1; + a += 1; + a -= 1; + return a; + }(42)); + } + expect: { + console.log(function(a){ + ++a; + --a; + ++a; + --a; + return a; + }(42)); + } + expect_stdout: "42" +} + +issue_3375_1: { + options = { + assignments: true, + reduce_vars: true, + } + input: { + function p(o) { + console.log(typeof o, o); + } + p(function(b) { + var a = b += 1; + --b; + return a; + }("object")); + } + expect: { + function p(o) { + console.log(typeof o, o); + } + p(function(b) { + var a = b += 1; + --b; + return a; + }("object")); + } + expect_stdout: "string object1" +} + +issue_3375_2: { + options = { + assignments: true, + reduce_vars: true, + } + input: { + function p(o) { + console.log(typeof o, o); + } + p(function(b) { + var a = b -= 1; + --b; + return a; + }("object")); + } + expect: { + function p(o) { + console.log(typeof o, o); + } + p(function(b) { + var a = --b; + --b; + return a; + }("object")); + } + expect_stdout: "number NaN" +} + +issue_3427: { + options = { + assignments: true, + sequences: true, + side_effects: true, + unused: true, + } + input: { + (function() { + var a; + a || (a = {}); + })(); + } + expect: {} +} + +issue_3429_1: { + options = { + assignments: true, + side_effects: true, + unused: true, + } + input: { + var a = "PASS"; + (function(b) { + b && (b = a = "FAIL"); + })(); + console.log(a); + } + expect: { + var a = "PASS"; + (function(b) { + b = b && (a = "FAIL"); + })(); + console.log(a); + } + expect_stdout: "PASS" +} + +issue_3429_2: { + options = { + assignments: true, + side_effects: true, + unused: true, + } + input: { + var a; + (function(b) { + b || (b = a = "FAIL"); + })(42); + console.log(a); + } + expect: { + var a; + (function(b) { + b = b || (a = "FAIL"); + })(42); + console.log(a); + } + expect_stdout: "undefined" +} + +issue_3949_1: { + options = { + assignments: true, + evaluate: true, + reduce_vars: true, + } + input: { + var a = 42; + function f() { + var b = a; + b = b >> 2; + return 100 + b; + } + console.log(f()); + } + expect: { + var a = 42; + function f() { + var b = a; + b >>= 2; + return 100 + b; + } + console.log(f()); + } + expect_stdout: "110" +} + +issue_3949_2: { + options = { + assignments: true, + evaluate: true, + reduce_vars: true, + } + input: { + var a = 42; + function f() { + var b = a; + b = 5 & b; + return 100 + b; + } + console.log(f()); + } + expect: { + var a = 42; + function f() { + var b = a; + b &= 5; + return 100 + b; + } + console.log(f()); + } + expect_stdout: "100" +} diff --git a/test/compress/collapse_vars.js b/test/compress/collapse_vars.js index 546e0d3b..cea5ca84 100644 --- a/test/compress/collapse_vars.js +++ b/test/compress/collapse_vars.js @@ -3001,6 +3001,7 @@ issue_2298: { expect: { !function() { (function() { + 0; try { !function(b) { (void 0)[1] = "foo"; diff --git a/test/compress/drop-unused.js b/test/compress/drop-unused.js index b21ca399..f3aeab21 100644 --- a/test/compress/drop-unused.js +++ b/test/compress/drop-unused.js @@ -2285,7 +2285,7 @@ issue_3598: { try { (function() { a = "PASS"; - var c = (void (c.p = 0))[!1]; + (void ((void 0).p = 0))[!1]; })(); } catch (e) {} console.log(a); @@ -2557,10 +2557,9 @@ issue_3899: { console.log(typeof a); } expect: { - 0; - var a = function() { + function a() { return 2; - }; + } console.log(typeof a); } expect_stdout: "function" @@ -2625,3 +2624,31 @@ assign_if_assign_read: { } expect_stdout: "PASS" } + +issue_3951: { + options = { + pure_getters: "strict", + reduce_vars: true, + side_effects: true, + toplevel: true, + unused: true, + } + input: { + var a = console.log("PASS"); + console.log(a); + a = "0"; + console.log(a.p = 0); + a && a; + } + expect: { + var a = console.log("PASS"); + console.log(a); + a = "0"; + console.log(a.p = 0); + } + expect_stdout: [ + "PASS", + "undefined", + "0", + ] +} diff --git a/test/compress/evaluate.js b/test/compress/evaluate.js index 4e3bc725..fd8deab5 100644 --- a/test/compress/evaluate.js +++ b/test/compress/evaluate.js @@ -1579,9 +1579,9 @@ issue_2968_1: { expect: { var c = "FAIL"; (function() { - b = -(a = 42), - void ((a <<= 0) && (a[(c = "PASS", 0 >>> (b += 1))] = 0)); - var a, b; + a = 42, + void ((a <<= 0) && (a[(c = "PASS", 0)] = 0)); + var a; })(); console.log(c); } @@ -2341,10 +2341,7 @@ issue_3878_1: { console.log(b ? "PASS" : "FAIL"); } expect: { - var b = function(a) { - return (a = 0) == (a && this > (a += 0)); - }(); - console.log(b ? "PASS" : "FAIL"); + console.log(true ? "PASS" : "FAIL"); } expect_stdout: "PASS" } @@ -2435,12 +2432,11 @@ issue_3903: { console.log(d); } expect: { - var a = "PASS"; function f(b, c) { return console, c; } - var d = f(f(), a = a); - console.log(d); + f(f(), "PASS"); + console.log("PASS"); } expect_stdout: "PASS" } @@ -2649,7 +2645,7 @@ issue_3933: { } expect: { (function(a, b) { - 1, (b ^= 1), console.log("PASS"); + 1, 1, console.log("PASS"); })(); } expect_stdout: "PASS" diff --git a/test/compress/join_vars.js b/test/compress/join_vars.js index 590f9970..9f0b35b7 100644 --- a/test/compress/join_vars.js +++ b/test/compress/join_vars.js @@ -808,9 +808,9 @@ issue_3795: { } expect: { var a = "FAIL", d = function() { - if (a = 42, d) return -1; + if (void 0) return -1; a = "PASS"; - }(); + }(a = 42); console.log(a, d); } expect_stdout: "PASS undefined" diff --git a/test/compress/keep_fargs.js b/test/compress/keep_fargs.js index e1737081..e42b3978 100644 --- a/test/compress/keep_fargs.js +++ b/test/compress/keep_fargs.js @@ -306,6 +306,7 @@ issue_2298: { expect: { !function() { (function() { + 0; try { !function() { (void 0)[1] = "foo"; diff --git a/test/compress/reduce_vars.js b/test/compress/reduce_vars.js index cb7599a9..3368cc6f 100644 --- a/test/compress/reduce_vars.js +++ b/test/compress/reduce_vars.js @@ -1520,8 +1520,7 @@ func_inline: { } expect: { function f() { - console.log(1 + h()); - var h; + console.log(1 + (void 0)()); } } } @@ -2671,8 +2670,8 @@ var_assign_6: { } expect: { !function() { - var a = function(){}(a = 1); - console.log(a); + (function(){}()); + console.log(void 0); }(); } expect_stdout: "undefined" @@ -7111,3 +7110,166 @@ issue_3922: { } expect_stdout: "PASS" } + +issue_3949_1: { + options = { + evaluate: true, + reduce_vars: true, + } + input: { + (function f(a) { + var a = void (a = 0, g); + function g() { + console.log(typeof a); + } + g(); + })(); + } + expect: { + (function f(a) { + var a = void (a = 0, g); + function g() { + console.log(typeof a); + } + g(); + })(); + } + expect_stdout: "undefined" +} + +issue_3949_2: { + options = { + reduce_vars: true, + unused: true, + } + input: { + (function f(a) { + var a = void (a = 0, g); + function g() { + console.log(typeof a); + } + g(); + })(); + } + expect: { + (function(a) { + a = void (a = 0, g); + function g() { + console.log(typeof a); + } + g(); + })(); + } + expect_stdout: "undefined" +} + +issue_3949_3: { + options = { + evaluate: true, + reduce_vars: true, + toplevel: true, + } + input: { + function f() {} + for (var a, i = 3; 0 <= --i; ) { + a = f; + console.log(a === b); + var b = a; + } + } + expect: { + function f() {} + for (var a, i = 3; 0 <= --i; ) { + a = f; + console.log(a === b); + var b = a; + } + } + expect_stdout: [ + "false", + "true", + "true", + ] +} + +issue_3949_4: { + options = { + reduce_vars: true, + unused: true, + toplevel: true, + } + input: { + function f() {} + for (var a, i = 3; 0 <= --i; ) { + a = f; + console.log(a === b); + var b = a; + } + } + expect: { + function f() {} + for (var a, i = 3; 0 <= --i; ) { + a = f; + console.log(a === b); + var b = a; + } + } + expect_stdout: [ + "false", + "true", + "true", + ] +} + +local_assignment_lambda: { + options = { + evaluate: true, + reduce_vars: true, + sequences: true, + toplevel: true, + unused: true, + } + input: { + var a = "FAIL"; + function f() { + a = "PASS"; + console.log(a); + } + f(); + f(); + } + expect: { + function f() { + console.log("PASS"); + } + f(), + f(); + } + expect_stdout: [ + "PASS", + "PASS", + ] +} + +local_assignment_loop: { + options = { + evaluate: true, + reduce_vars: true, + sequences: true, + toplevel: true, + unused: true, + } + input: { + var a = "FAIL"; + do { + a = "PASS"; + console.log(a); + } while (!console); + } + expect: { + do { + console.log("PASS"); + } while (!console); + } + expect_stdout: "PASS" +} diff --git a/test/compress/side_effects.js b/test/compress/side_effects.js index 8c263d47..63282660 100644 --- a/test/compress/side_effects.js +++ b/test/compress/side_effects.js @@ -97,9 +97,8 @@ issue_2233_2: { var RegExp; UndeclaredGlobal; function foo() { - var Number; AnotherUndeclaredGlobal; - Number.isNaN; + (void 0).isNaN; } } } -- cgit v1.2.3