fix corner case in sign propagation (#3696)

- migrate de-facto functionality to `evaluate`

fixes #3695
This commit is contained in:
Alex Lam S.L
2020-01-28 22:44:18 +08:00
committed by GitHub
parent b499e03f82
commit 87119e44a0
3 changed files with 30 additions and 9 deletions

View File

@@ -6062,6 +6062,8 @@ merge(Compressor.prototype, {
return self; return self;
}); });
var SIGN_OPS = makePredicate("+ -");
var MULTIPLICATIVE_OPS = makePredicate("* / %");
OPT(AST_UnaryPrefix, function(self, compressor) { OPT(AST_UnaryPrefix, function(self, compressor) {
var e = self.expression; var e = self.expression;
if (compressor.option("evaluate") if (compressor.option("evaluate")
@@ -6112,12 +6114,12 @@ merge(Compressor.prototype, {
])).optimize(compressor); ])).optimize(compressor);
} }
} }
if (self.operator == "-" && e instanceof AST_Infinity) { if (self.operator == "-" && e instanceof AST_Infinity) e = e.transform(compressor);
e = e.transform(compressor); if (compressor.option("evaluate")
} && e instanceof AST_Binary
if (e instanceof AST_Binary && SIGN_OPS[self.operator]
&& (self.operator == "+" || self.operator == "-") && MULTIPLICATIVE_OPS[e.operator]
&& (e.operator == "*" || e.operator == "/" || e.operator == "%")) { && (e.left.is_constant() || !e.right.has_side_effects(compressor))) {
return make_node(AST_Binary, self, { return make_node(AST_Binary, self, {
operator: e.operator, operator: e.operator,
left: make_node(AST_UnaryPrefix, e.left, { left: make_node(AST_UnaryPrefix, e.left, {
@@ -6387,7 +6389,8 @@ merge(Compressor.prototype, {
if (self.right instanceof AST_Binary if (self.right instanceof AST_Binary
&& self.operator == self.right.operator && self.operator == self.right.operator
&& (self.left.is_string(compressor) && self.right.is_string(compressor) && (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(); swap_chain();
} }
} }
@@ -7084,7 +7087,7 @@ merge(Compressor.prototype, {
return reachable; return reachable;
} }
var ASSIGN_OPS = makePredicate("+ - / * % >> << >>> | ^ &"); var ASSIGN_OPS = makePredicate("+ - * / % >> << >>> | ^ &");
var ASSIGN_OPS_COMMUTATIVE = makePredicate("* | ^ &"); var ASSIGN_OPS_COMMUTATIVE = makePredicate("* | ^ &");
OPT(AST_Assign, function(self, compressor) { OPT(AST_Assign, function(self, compressor) {
if (compressor.option("dead_code")) { if (compressor.option("dead_code")) {

View File

@@ -46,7 +46,7 @@ mangle_props: {
obj[1/0], obj[1/0],
obj["Infinity"], obj["Infinity"],
obj[-1/0], obj[-1/0],
obj[-1/0], obj[-(1/0)],
obj["-Infinity"], obj["-Infinity"],
obj[null], obj[null],
obj["null"] obj["null"]

View File

@@ -669,6 +669,9 @@ issue_1710: {
} }
unary_binary_parenthesis: { unary_binary_parenthesis: {
options = {
evaluate: true,
}
input: { input: {
var v = [ 0, 1, NaN, Infinity, null, undefined, true, false, "", "foo", /foo/ ]; var v = [ 0, 1, NaN, Infinity, null, undefined, true, false, "", "foo", /foo/ ];
v.forEach(function(x) { v.forEach(function(x) {
@@ -1233,3 +1236,18 @@ issue_3684: {
"Infinity", "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"
}