diff --git a/lib/compress.js b/lib/compress.js index 211f6b2564..74e09299b2 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -646,14 +646,12 @@ Compressor.prototype.compress = function(node) { scope.may_call_this = undefined; } - function push(tw, sequential) { + function push(tw, sequential, conditional) { var defined_ids = Object.create(tw.defined_ids); - var safe_ids = Object.create(tw.safe_ids); - if (!sequential) { - defined_ids.seq = Object.create(null); - safe_ids.seq = {}; - } + if (!sequential || conditional) defined_ids.seq = Object.create(null); tw.defined_ids = defined_ids; + var safe_ids = Object.create(tw.safe_ids); + if (!sequential) safe_ids.seq = {}; tw.safe_ids = safe_ids; } @@ -855,7 +853,7 @@ Compressor.prototype.compress = function(node) { var scanner = new TreeWalker(function(node) { if (node instanceof AST_DefaultValue) { reset_flags(node); - push(tw, true); + push(tw, true, true); node.value.walk(tw); pop(tw); var save = fixed; @@ -1042,7 +1040,7 @@ Compressor.prototype.compress = function(node) { return walk_lazy(); } var safe = safe_to_read(tw, ld); - if (lazy) push(tw, true); + if (lazy) push(tw, true, true); right.walk(tw); if (lazy) pop(tw); if (safe && !left.in_arg && safe_to_assign(tw, ld)) { @@ -1127,7 +1125,7 @@ Compressor.prototype.compress = function(node) { function walk_lazy() { if (!lazy) return; left.walk(tw); - push(tw, true); + push(tw, true, true); right.walk(tw); pop(tw); return true; @@ -1136,7 +1134,7 @@ Compressor.prototype.compress = function(node) { def(AST_Binary, function(tw) { if (!lazy_op[this.operator]) return; this.left.walk(tw); - push(tw, true); + push(tw, true, true); this.right.walk(tw); pop(tw); return true; @@ -1166,7 +1164,7 @@ Compressor.prototype.compress = function(node) { } exp.walk(tw); var optional = node.optional; - if (optional) push(tw, true); + if (optional) push(tw, true, true); node.args.forEach(function(arg) { arg.walk(tw); }); @@ -1251,16 +1249,16 @@ Compressor.prototype.compress = function(node) { }); def(AST_Conditional, function(tw) { this.condition.walk(tw); - push(tw, true); + push(tw, true, true); this.consequent.walk(tw); pop(tw); - push(tw, true); + push(tw, true, true); this.alternative.walk(tw); pop(tw); return true; }); def(AST_DefaultValue, function(tw) { - push(tw, true); + push(tw, true, true); this.value.walk(tw); pop(tw); this.name.walk(tw); @@ -1349,11 +1347,11 @@ Compressor.prototype.compress = function(node) { }); def(AST_If, function(tw) { this.condition.walk(tw); - push(tw, true); + push(tw, true, true); this.body.walk(tw); pop(tw); if (this.alternative) { - push(tw, true); + push(tw, true, true); this.alternative.walk(tw); pop(tw); } @@ -1396,7 +1394,7 @@ Compressor.prototype.compress = function(node) { var expr = node.expression; if (node.optional) { expr.walk(tw); - push(tw, true); + push(tw, true, true); node.property.walk(tw); pop(tw); } else { @@ -1420,7 +1418,7 @@ Compressor.prototype.compress = function(node) { branch.expression.walk(tw); if (first) { first = false; - push(tw, true); + push(tw, true, true); } }); if (!first) pop(tw); @@ -1428,7 +1426,7 @@ Compressor.prototype.compress = function(node) { return true; }); def(AST_SwitchBranch, function(tw) { - push(tw, true); + push(tw, true, true); walk_body(this, tw); pop(tw); return true; @@ -1567,7 +1565,7 @@ Compressor.prototype.compress = function(node) { walk_body(node, tw); pop(tw); if (node.bcatch) { - push(tw, true); + push(tw, true, true); node.bcatch.walk(tw); pop(tw); } diff --git a/test/compress/optional-chains.js b/test/compress/optional-chains.js index a1594cf618..2a337e6c7e 100644 --- a/test/compress/optional-chains.js +++ b/test/compress/optional-chains.js @@ -693,3 +693,35 @@ issue_5905: { expect_stdout: "PASS" node_version: ">=14" } + +issue_5912: { + options = { + pure_getters: "strict", + reduce_vars: true, + side_effects: true, + } + input: { + var a, b = {}; + b = b.p; + a?.[b.q]; + try { + b.r; + console.log("FAIL"); + } catch (e) { + console.log("PASS"); + } + } + expect: { + var a, b = {}; + b = b.p; + a?.[b.q]; + try { + b.r; + console.log("FAIL"); + } catch (e) { + console.log("PASS"); + } + } + expect_stdout: "PASS" + node_version: ">=14" +} diff --git a/test/compress/side_effects.js b/test/compress/side_effects.js index 9a7a4eb917..5ad46956ff 100644 --- a/test/compress/side_effects.js +++ b/test/compress/side_effects.js @@ -967,3 +967,104 @@ issue_5860_keep_3: { } expect_stdout: "PASS" } + +issue_5912_1: { + options = { + pure_getters: "strict", + reduce_vars: true, + side_effects: true, + } + input: { + var a = {}; + a = a.p; + console || a.q; + try { + a.r; + console.log("FAIL"); + } catch (e) { + console.log("PASS"); + } + } + expect: { + var a = {}; + a = a.p; + console || a.q; + try { + a.r; + console.log("FAIL"); + } catch (e) { + console.log("PASS"); + } + } + expect_stdout: "PASS" +} + +issue_5912_2: { + options = { + pure_getters: "strict", + reduce_vars: true, + side_effects: true, + } + input: { + var a = {}; + a = a.p; + if (!console) a.q; + try { + a.r; + console.log("FAIL"); + } catch (e) { + console.log("PASS"); + } + } + expect: { + var a = {}; + a = a.p; + if (!console) a.q; + try { + a.r; + console.log("FAIL"); + } catch (e) { + console.log("PASS"); + } + } + expect_stdout: "PASS" +} + +issue_5912_3: { + options = { + pure_getters: "strict", + reduce_vars: true, + side_effects: true, + } + input: { + var a = {}; + a = a.p; + try { + console; + } catch (e) { + a.q; + } + try { + a.r; + console.log("FAIL"); + } catch (e) { + console.log("PASS"); + } + } + expect: { + var a = {}; + a = a.p; + try { + console; + } catch (e) { + a.q; + } + try { + a.r; + console.log("FAIL"); + } catch (e) { + console.log("PASS"); + } + } + expect_stdout: "PASS" +} diff --git a/test/compress/switches.js b/test/compress/switches.js index 681a919925..3c70fd0c62 100644 --- a/test/compress/switches.js +++ b/test/compress/switches.js @@ -1798,3 +1798,77 @@ issue_5892_2: { } expect_stdout: "PASS" } + +issue_5912_1: { + options = { + pure_getters: "strict", + reduce_vars: true, + side_effects: true, + } + input: { + var a = {}; + a = a.p; + switch (console) { + case 42: + a.q; + } + try { + a.r; + console.log("FAIL"); + } catch (e) { + console.log("PASS"); + } + } + expect: { + var a = {}; + a = a.p; + switch (console) { + case 42: + a.q; + } + try { + a.r; + console.log("FAIL"); + } catch (e) { + console.log("PASS"); + } + } + expect_stdout: "PASS" +} + +issue_5912_2: { + options = { + pure_getters: "strict", + reduce_vars: true, + side_effects: true, + } + input: { + var a, b = {}; + b = b.p; + switch (a) { + case void 0: + case b.q: + } + try { + b.r; + console.log("FAIL"); + } catch (e) { + console.log("PASS"); + } + } + expect: { + var a, b = {}; + b = b.p; + switch (a) { + case void 0: + case b.q: + } + try { + b.r; + console.log("FAIL"); + } catch (e) { + console.log("PASS"); + } + } + expect_stdout: "PASS" +}