From 19d232badb0d9b16f447e89c33998fcf542496ce Mon Sep 17 00:00:00 2001 From: "Alex Lam S.L" Date: Fri, 7 May 2021 12:38:22 +0100 Subject: [PATCH] fix corner case in `unused` (#4913) fixes #4912 --- lib/compress.js | 21 ++++++--- test/compress/drop-unused.js | 84 +++++++++++++++++++++++++++++++++++- 2 files changed, 97 insertions(+), 8 deletions(-) diff --git a/lib/compress.js b/lib/compress.js index ba683e2402..7b871e4141 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -6030,8 +6030,10 @@ merge(Compressor.prototype, { } if (node instanceof AST_Definitions) { node.definitions.forEach(function(defn) { - var side_effects = defn.value - && (defn.name instanceof AST_Destructured || defn.value.has_side_effects(compressor)); + var value = defn.value; + var side_effects = value + && (defn.name instanceof AST_Destructured || value.has_side_effects(compressor)); + var shared = side_effects && value.tail_node().operator == "="; defn.name.mark_symbol(function(name) { if (!(name instanceof AST_SymbolDeclaration)) return; var def = name.definition(); @@ -6046,13 +6048,17 @@ merge(Compressor.prototype, { in_use_ids[def.id] = true; in_use.push(def); } - if (defn.value) { - if (!side_effects) initializations.add(def.id, defn.value); + if (value) { + if (!side_effects) { + initializations.add(def.id, value); + } else if (shared) { + verify_safe_usage(def, true, value_modified[def.id]); + } assignments.add(def.id, defn); } return true; }, tw); - if (side_effects) defn.value.walk(tw); + if (side_effects) value.walk(tw); }); return true; } @@ -6755,14 +6761,15 @@ merge(Compressor.prototype, { prop.walk(tw); }); if (node instanceof AST_Assign) { - var right = get_rhs(node); + var right = get_rhs(node), shared = false; if (init && node.write_only === true && node_def.scope === self && !right.has_side_effects(compressor)) { initializations.add(node_def.id, right); } else { right.walk(tw); + shared = right.tail_node().operator == "="; } if (node.left === sym) { - if (!node.write_only) { + if (!node.write_only || shared) { verify_safe_usage(node_def, true, value_modified[node_def.id]); } } else { diff --git a/test/compress/drop-unused.js b/test/compress/drop-unused.js index 6c4ca291de..709ed92219 100644 --- a/test/compress/drop-unused.js +++ b/test/compress/drop-unused.js @@ -2382,7 +2382,7 @@ issue_3664: { } expect: { console.log(function() { - var b = (b && console.log("FAIL"), 0, 0); + var a, b = (a = (a = [ b && console.log("FAIL") ]).p = 0, 0); return "PASS"; }()); } @@ -3388,3 +3388,85 @@ issue_4834: { } expect_stdout: "PASS" } + +issue_4912_1: { + options = { + pure_getters: "strict", + reduce_vars: true, + toplevel: true, + unused: true, + } + input: { + var a = A = function() {}; + A; + a.prototype = { + f: function() { + console.log("PASS"); + }, + }; + new A().f(); + } + expect: { + var a = A = function() {}; + A; + a.prototype = { + f: function() { + console.log("PASS"); + }, + }; + new A().f(); + } + expect_stdout: "PASS" +} + +issue_4912_2: { + options = { + pure_getters: "strict", + unused: true, + } + input: { + console.log(function() { + var g, f = function() {}; + f.p = {}; + (g = f.p.q = function() {}).r = "PASS"; + return f; + }().p.q.r); + } + expect: { + console.log(function() { + var g, f = function() {}; + f.p = {}; + (g = f.p.q = function() {}).r = "PASS"; + return f; + }().p.q.r); + } + expect_stdout: "PASS" +} + +issue_4912_3: { + options = { + pure_getters: "strict", + reduce_vars: true, + side_effects: true, + unused: true, + } + input: { + console.log(function(f, g) { + f = function() {}; + f.p = {}; + g = f.p.q = function() {}; + g.r = "PASS"; + return f; + }().p.q.r); + } + expect: { + console.log(function(f, g) { + f = function() {}; + f.p = {}; + g = f.p.q = function() {}; + g.r = "PASS"; + return f; + }().p.q.r); + } + expect_stdout: "PASS" +}