From dabcc39b5138b6e9c84bfd1733bea220edee6d34 Mon Sep 17 00:00:00 2001 From: "Alex Lam S.L" Date: Mon, 3 Oct 2022 15:47:15 +0100 Subject: [PATCH] fix corner cases in `booleans` & `conditionals` (#5695) fixes #5694 --- lib/compress.js | 16 +++++++++------ test/compress/booleans.js | 17 ++++++++++++++++ test/compress/comparisons.js | 2 -- test/compress/conditionals.js | 18 +++++++++++++++++ test/compress/if_return.js | 38 +++++++++++++++++------------------ 5 files changed, 64 insertions(+), 27 deletions(-) diff --git a/lib/compress.js b/lib/compress.js index ea65992c..338b05f0 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -1748,6 +1748,7 @@ Compressor.prototype.compress = function(node) { var identifier_atom = makePredicate("Infinity NaN undefined"); function is_lhs_read_only(lhs, compressor) { + if (lhs instanceof AST_Atom) return true; if (lhs instanceof AST_ObjectIdentity) return true; if (lhs instanceof AST_PropAccess) { if (lhs.property === "__proto__") return true; @@ -11589,10 +11590,12 @@ Compressor.prototype.compress = function(node) { if (node instanceof AST_Unary) return true; } - function extract_lhs(node) { - if (node instanceof AST_Assign) return node.left; + function extract_lhs(node, compressor) { + if (node instanceof AST_Assign) return is_lhs_read_only(node.left, compressor) ? node : node.left; if (node instanceof AST_Sequence) return extract_lhs(node.tail_node()); - if (node instanceof AST_UnaryPrefix && UNARY_POSTFIX[node.operator]) return node.expression; + if (node instanceof AST_UnaryPrefix && UNARY_POSTFIX[node.operator]) { + return is_lhs_read_only(node.expression, compressor) ? node : node.expression; + } return node; } @@ -11601,6 +11604,7 @@ Compressor.prototype.compress = function(node) { if (node instanceof AST_Sub) { return repeatable(compressor, node.expression) && repeatable(compressor, node.property); } + if (node instanceof AST_Symbol) return true; return !node.has_side_effects(compressor); } @@ -11637,7 +11641,7 @@ Compressor.prototype.compress = function(node) { if (seq !== self) return seq.optimize(compressor); } if (compressor.option("assignments") && lazy_op[self.operator]) { - var lhs = extract_lhs(self.left); + var lhs = extract_lhs(self.left, compressor); var right = self.right; // a || (a = x) ---> a = a || x // (a = x) && (a = y) ---> a = (a = x) && y @@ -11737,7 +11741,7 @@ Compressor.prototype.compress = function(node) { var in_bool = false; var parent = compressor.parent(); if (compressor.option("booleans")) { - var lhs = extract_lhs(self.left); + var lhs = extract_lhs(self.left, compressor); if (lazy_op[self.operator] && !lhs.has_side_effects(compressor)) { // a || a ---> a // (a = x) && a --> a = x @@ -12898,7 +12902,7 @@ Compressor.prototype.compress = function(node) { } var consequent = self.consequent; var alternative = self.alternative; - var cond_lhs = extract_lhs(condition); + var cond_lhs = extract_lhs(condition, compressor); if (repeatable(compressor, cond_lhs)) { // x ? x : y ---> x || y if (cond_lhs.equals(consequent)) return make_node(AST_Binary, self, { diff --git a/test/compress/booleans.js b/test/compress/booleans.js index aabb3805..d8e62004 100644 --- a/test/compress/booleans.js +++ b/test/compress/booleans.js @@ -830,3 +830,20 @@ issue_5469: { } expect_stdout: "undefined" } + +issue_5694: { + options = { + booleans: true, + conditionals: true, + } + input: { + var undefined; + // Node.js v0.12~6 (vm): 42 + console.log((undefined = 42) && undefined); + } + expect: { + var undefined; + console.log((undefined = 42) && undefined); + } + expect_stdout: true +} diff --git a/test/compress/comparisons.js b/test/compress/comparisons.js index d187c2d7..bc860ce9 100644 --- a/test/compress/comparisons.js +++ b/test/compress/comparisons.js @@ -76,14 +76,12 @@ self_comparison_1: { comparisons: true, } input: { - var a, b; a === a; a !== b; b.c === a.c; b.c !== b.c; } expect: { - var a, b; a == a; a !== b; b.c === a.c; diff --git a/test/compress/conditionals.js b/test/compress/conditionals.js index e5c903ed..f42cce97 100644 --- a/test/compress/conditionals.js +++ b/test/compress/conditionals.js @@ -3033,3 +3033,21 @@ issue_5673_2: { } expect_stdout: "PASS" } + +issue_5694: { + options = { + conditionals: true, + } + input: { + FORCE_EXEC = "async()=>{}"; + var a = "foo"; + // Node.js v0.12~6 (vm): foo + console.log((NaN = a) ? NaN : 42); + } + expect: { + FORCE_EXEC = "async()=>{}"; + var a = "foo"; + console.log((NaN = a) ? NaN : 42); + } + expect_stdout: "NaN" +} diff --git a/test/compress/if_return.js b/test/compress/if_return.js index fc077d31..d993ca22 100644 --- a/test/compress/if_return.js +++ b/test/compress/if_return.js @@ -976,33 +976,33 @@ nested_if_return: { if_return: true, } input: { - function f(a, b, c, d, e, f, g, h, i, j, k, l, m, n) { - if (a) { - if (b) - return b; - if (c) - return d; - if (e) - return f; - if (g) - return h; - if (i) { - if (j) - return k; + function f() { + if (A) { + if (B) + return B; + if (C) + return D; + if (E) + return F; + if (G) + return H; + if (I) { + if (J) + return K; return; } - if (l) { - if (m) + if (L) { + if (M) return; - return n; + return N; } } } } expect: { - function f(a, b, c, d, e, f, g, h, i, j, k, l, m, n) { - if (a) - return b || (c ? d : e ? f : g ? h : i ? j ? k : void 0 : l && !m ? n : void 0); + function f() { + if (A) + return B || (C ? D : E ? F : G ? H : I ? J ? K : void 0 : L && !M ? N : void 0); } } }