From f07dc5cfba57d607c8f256fb8f339a29a4aeb09a Mon Sep 17 00:00:00 2001 From: "Alex Lam S.L" Date: Sat, 7 Jan 2023 12:27:18 +0200 Subject: [PATCH] fix corner case in `merge_vars` (#5773) fixes #5772 --- lib/compress.js | 37 ++++++++++++++--------- test/compress/merge_vars.js | 58 +++++++++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+), 14 deletions(-) diff --git a/lib/compress.js b/lib/compress.js index 39a1da6ac19..9749095bea6 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -6648,49 +6648,58 @@ Compressor.prototype.compress = function(node) { function walk_cond(condition, consequent, alternative) { var save = segment; - var segments = scan_branches(condition, consequent, alternative); + var segments = scan_branches(1, condition, consequent, alternative); if (consequent) { - segment = segments[0]; - pop(); + segment = segments.consequent.segment; + for (var i = segments.consequent.level; --i >= 0;) pop(); if (segment !== save) return; } if (alternative) { - segment = segments[1]; - pop(); + segment = segments.alternative.segment; + for (var i = segments.alternative.level; --i >= 0;) pop(); if (segment !== save) return; } segment = save; } - function scan_branches(condition, consequent, alternative) { - var segments = [ segment, segment ]; + function scan_branches(level, condition, consequent, alternative) { + var segments = { + consequent: { + segment: segment, + level: level, + }, + alternative: { + segment: segment, + level: level, + }, + } if (condition instanceof AST_Binary) switch (condition.operator) { case "&&": - segments[0] = scan_branches(condition.left, condition.right)[0]; + segments.consequent = scan_branches(level + 1, condition.left, condition.right).consequent; break; case "||": case "??": - segments[1] = scan_branches(condition.left, null, condition.right)[1]; + segments.alternative = scan_branches(level + 1, condition.left, null, condition.right).alternative; break; default: condition.walk(tw); break; } else if (condition instanceof AST_Conditional) { - scan_branches(condition.condition, condition.consequent, condition.alternative); + scan_branches(level + 1, condition.condition, condition.consequent, condition.alternative); } else { condition.walk(tw); } if (consequent) { - segment = segments[0]; + segment = segments.consequent.segment; push(); consequent.walk(tw); - segments[0] = segment; + segments.consequent.segment = segment; } if (alternative) { - segment = segments[1]; + segment = segments.alternative.segment; push(); alternative.walk(tw); - segments[1] = segment; + segments.alternative.segment = segment; } return segments; } diff --git a/test/compress/merge_vars.js b/test/compress/merge_vars.js index 58563083103..e00bc3b9ed9 100644 --- a/test/compress/merge_vars.js +++ b/test/compress/merge_vars.js @@ -3942,3 +3942,61 @@ issue_5770_2: { } expect_stdout: "PASS" } + +issue_5772_1: { + options = { + dead_code: true, + merge_vars: true, + loops: true, + } + input: { + (function(a) { + while (--a) + return; + var b = console.log("foo") && (c = 42) ? 0 : console.log(c); + var c = b; + })(); + } + expect: { + (function(a) { + if (--a) + return; + var a = console.log("foo") && (c = 42) ? 0 : console.log(c); + var c = a; + })(); + } + expect_stdout: [ + "foo", + "undefined", + ] +} + +issue_5772_2: { + options = { + dead_code: true, + merge_vars: true, + loops: true, + } + input: { + (function(a) { + while (--a) + return; + var b; + var c = console.log("foo") && (b = 1) ? 2 : 3; + console.log(b, c); + })(); + } + expect: { + (function(a) { + if (--a) + return; + var b; + var a = console.log("foo") && (b = 1) ? 2 : 3; + console.log(b, a); + })(); + } + expect_stdout: [ + "foo", + "undefined 3", + ] +}