From 95d3ede664598916e6dced8a5e0f5003efd3c77a Mon Sep 17 00:00:00 2001 From: "Alex Lam S.L" Date: Thu, 20 Jun 2024 17:43:55 +0300 Subject: [PATCH] fix corner cases in `pure_getters` & `reduce_vars` (#5859) fixes #5856 fixes #5857 fixes #5858 --- lib/compress.js | 39 +++++++++++++++++++------------- test/compress/issue-5614.js | 2 +- test/compress/optional-chains.js | 30 ++++++++++++++++++++++++ test/compress/pure_getters.js | 28 +++++++++++++++++++++++ 4 files changed, 82 insertions(+), 17 deletions(-) diff --git a/lib/compress.js b/lib/compress.js index ff5652e4ba9..aaaf08b4714 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -1261,8 +1261,9 @@ Compressor.prototype.compress = function(node) { }); def(AST_Dot, function(tw, descend) { descend(); - var expr = this.expression; - if (expr instanceof AST_SymbolRef) access(tw, expr.definition()); + var node = this; + var expr = node.expression; + if (!node.optional && expr instanceof AST_SymbolRef) access(tw, expr.definition()); return true; }); def(AST_For, function(tw, descend, compressor) { @@ -1362,15 +1363,18 @@ Compressor.prototype.compress = function(node) { pop_scope(tw, fn); return true; }); - def(AST_Sub, function(tw) { + def(AST_Sub, function(tw, descend) { var node = this; - if (!node.optional) return; var expr = node.expression; - expr.walk(tw); - if (expr instanceof AST_SymbolRef) access(tw, expr.definition()); - push(tw, true); - node.property.walk(tw); - pop(tw); + if (node.optional) { + expr.walk(tw); + push(tw, true); + node.property.walk(tw); + pop(tw); + } else { + descend(); + if (expr instanceof AST_SymbolRef) access(tw, expr.definition()); + } return true; }); def(AST_Switch, function(tw, descend, compressor) { @@ -8020,8 +8024,14 @@ Compressor.prototype.compress = function(node) { prop.walk(tw); }); if (node instanceof AST_Assign) { - var right = get_rhs(node), shared = false; - if (init && node.write_only === true && !right.has_side_effects(compressor)) { + var fixed = sym.fixed_value(); + var right = get_rhs(node); + var safe = fixed && fixed.is_constant(); + var shared = false; + if (init + && node.write_only === true + && (safe || node.left === sym || right.equals(sym)) + && !right.has_side_effects(compressor)) { initializations.add(node_def.id, right); } else { right.walk(tw); @@ -8031,11 +8041,8 @@ Compressor.prototype.compress = function(node) { if (!node.write_only || shared) { verify_safe_usage(node_def, sym, value_modified[node_def.id]); } - } else { - var fixed = sym.fixed_value(); - if (!fixed || !fixed.is_constant()) { - verify_safe_usage(node_def, value_read[node_def.id], true); - } + } else if (!safe) { + verify_safe_usage(node_def, value_read[node_def.id], true); } } if (track_assigns(node_def, sym) && is_lhs(sym, node) !== sym) add_assigns(node_def, sym); diff --git a/test/compress/issue-5614.js b/test/compress/issue-5614.js index bdf6bfe17aa..27488731129 100644 --- a/test/compress/issue-5614.js +++ b/test/compress/issue-5614.js @@ -26,7 +26,7 @@ record_update: { currying: { options = { inline: true, - passes: 2, + passes: 3, pure_getters: "strict", reduce_funcs: true, reduce_vars: true, diff --git a/test/compress/optional-chains.js b/test/compress/optional-chains.js index fcff9a8a94d..4352bb66050 100644 --- a/test/compress/optional-chains.js +++ b/test/compress/optional-chains.js @@ -617,3 +617,33 @@ issue_5292_sub_pure_getters_strict: { ] node_version: ">=14" } + +issue_5856: { + options = { + pure_getters: "strict", + reduce_vars: true, + side_effects: true, + } + input: { + try { + var a; + a?.p; + a.q; + console.log("FAIL"); + } catch (e) { + console.log("PASS"); + } + } + expect: { + try { + var a; + a?.p; + a.q; + console.log("FAIL"); + } catch (e) { + console.log("PASS"); + } + } + expect_stdout: "PASS" + node_version: ">=14" +} diff --git a/test/compress/pure_getters.js b/test/compress/pure_getters.js index a06570c98e7..7f2ec4e8810 100644 --- a/test/compress/pure_getters.js +++ b/test/compress/pure_getters.js @@ -1687,3 +1687,31 @@ issue_4939: { } expect_stdout: "PASS" } + +issue_5856: { + options = { + pure_getters: true, + reduce_vars: true, + side_effects: true, + unused: true, + } + input: { + var a = [ "FAIL", "PASS" ]; + (function(b) { + var c = b[0]; + b[0] = b[1]; + b[1] = c; + })(a); + console.log(a[0]); + } + expect: { + var a = [ "FAIL", "PASS" ]; + (function(b) { + var c = b[0]; + b[0] = b[1]; + b[1] = c; + })(a); + console.log(a[0]); + } + expect_stdout: "PASS" +}