From 87119e44a08118bf302a4da6ae71e74f8bea4f89 Mon Sep 17 00:00:00 2001 From: "Alex Lam S.L" Date: Tue, 28 Jan 2020 22:44:18 +0800 Subject: [PATCH] fix corner case in sign propagation (#3696) - migrate de-facto functionality to `evaluate` fixes #3695 --- lib/compress.js | 19 +++++++++++-------- test/compress/issue-1770.js | 2 +- test/compress/numbers.js | 18 ++++++++++++++++++ 3 files changed, 30 insertions(+), 9 deletions(-) diff --git a/lib/compress.js b/lib/compress.js index f2dfb64c..9b054ca3 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -6062,6 +6062,8 @@ merge(Compressor.prototype, { return self; }); + var SIGN_OPS = makePredicate("+ -"); + var MULTIPLICATIVE_OPS = makePredicate("* / %"); OPT(AST_UnaryPrefix, function(self, compressor) { var e = self.expression; if (compressor.option("evaluate") @@ -6112,12 +6114,12 @@ merge(Compressor.prototype, { ])).optimize(compressor); } } - if (self.operator == "-" && e instanceof AST_Infinity) { - e = e.transform(compressor); - } - if (e instanceof AST_Binary - && (self.operator == "+" || self.operator == "-") - && (e.operator == "*" || e.operator == "/" || e.operator == "%")) { + if (self.operator == "-" && e instanceof AST_Infinity) e = e.transform(compressor); + if (compressor.option("evaluate") + && e instanceof AST_Binary + && SIGN_OPS[self.operator] + && MULTIPLICATIVE_OPS[e.operator] + && (e.left.is_constant() || !e.right.has_side_effects(compressor))) { return make_node(AST_Binary, self, { operator: e.operator, left: make_node(AST_UnaryPrefix, e.left, { @@ -6387,7 +6389,8 @@ merge(Compressor.prototype, { if (self.right instanceof AST_Binary && self.operator == self.right.operator && (self.left.is_string(compressor) && self.right.is_string(compressor) - || self.right.left.is_string(compressor) && !self.right.right.has_side_effects(compressor))) { + || self.right.left.is_string(compressor) + && (self.left.is_constant() || !self.right.right.has_side_effects(compressor)))) { swap_chain(); } } @@ -7084,7 +7087,7 @@ merge(Compressor.prototype, { return reachable; } - var ASSIGN_OPS = makePredicate("+ - / * % >> << >>> | ^ &"); + var ASSIGN_OPS = makePredicate("+ - * / % >> << >>> | ^ &"); var ASSIGN_OPS_COMMUTATIVE = makePredicate("* | ^ &"); OPT(AST_Assign, function(self, compressor) { if (compressor.option("dead_code")) { diff --git a/test/compress/issue-1770.js b/test/compress/issue-1770.js index 7a529b2c..cd86d9d5 100644 --- a/test/compress/issue-1770.js +++ b/test/compress/issue-1770.js @@ -46,7 +46,7 @@ mangle_props: { obj[1/0], obj["Infinity"], obj[-1/0], - obj[-1/0], + obj[-(1/0)], obj["-Infinity"], obj[null], obj["null"] diff --git a/test/compress/numbers.js b/test/compress/numbers.js index e6f6ce23..9fca46f3 100644 --- a/test/compress/numbers.js +++ b/test/compress/numbers.js @@ -669,6 +669,9 @@ issue_1710: { } unary_binary_parenthesis: { + options = { + evaluate: true, + } input: { var v = [ 0, 1, NaN, Infinity, null, undefined, true, false, "", "foo", /foo/ ]; v.forEach(function(x) { @@ -1233,3 +1236,18 @@ issue_3684: { "Infinity", ] } + +issue_3695: { + options = { + evaluate: true, + } + input: { + var a = []; + console.log(+(a * (a[0] = false))); + } + expect: { + var a = []; + console.log(+(a * (a[0] = false))); + } + expect_stdout: "NaN" +} -- 2.34.1