From 78c8efd851411a3605f667e78efaa342a1c65b53 Mon Sep 17 00:00:00 2001 From: "Alex Lam S.L" Date: Sun, 29 Dec 2019 21:16:53 +0800 Subject: fix corner case in `evaluate` (#3656) fixes #3655 --- lib/compress.js | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) (limited to 'lib') diff --git a/lib/compress.js b/lib/compress.js index 9045a8dd..9c60d0ae 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -5998,6 +5998,7 @@ merge(Compressor.prototype, { }); var indexFns = makePredicate("indexOf lastIndexOf"); + var minus_zero_op = makePredicate("- * / %"); var commutativeOperators = makePredicate("== === != !== * & | ^"); function is_object(node) { return node instanceof AST_Array @@ -6459,11 +6460,11 @@ merge(Compressor.prototype, { // 0 + n => n case "+": if (self.left.value == 0) { - if (self.right.is_number(compressor)) return self.right; if (self.right.is_boolean(compressor)) return make_node(AST_UnaryPrefix, self, { operator: "+", expression: self.right }).optimize(compressor); + if (self.right.is_number(compressor) && !may_be_minus_zero(self.right)) return self.right; } break; // 1 * n => n @@ -6479,8 +6480,12 @@ merge(Compressor.prototype, { if (self.right instanceof AST_Number && !self.left.is_constant()) switch (self.operator) { // n + 0 => n case "+": - if (self.right.value == 0 && (self.left.is_boolean(compressor) || self.left.is_number(compressor))) { - return self.left; + if (self.right.value == 0) { + if (self.left.is_boolean(compressor)) return make_node(AST_UnaryPrefix, self, { + operator: "+", + expression: self.left + }).optimize(compressor); + if (self.left.is_number(compressor) && !may_be_minus_zero(self.left)) return self.left; } break; // n - 0 => n @@ -6635,6 +6640,20 @@ merge(Compressor.prototype, { && self.left.expression instanceof AST_Number && self.left.expression.value == 1; } } + + function may_be_minus_zero(node) { + var ev = node.evaluate(compressor); + if (ev instanceof AST_Node) { + var op = ev.operator; + if (!op) return true; + if (ev instanceof AST_Assign) { + if (op == "=") return may_be_minus_zero(ev.right); + op = op.slice(0, -1); + } + if (minus_zero_op[op]) return true; + if (ev instanceof AST_UnaryPrefix && op == "+") return true; + } else if (ev == 0 && 1 / ev < 0) return true; + } }); function recursive_ref(compressor, def) { -- cgit v1.2.3