fix corner case in unsafe_math (#4543)

fixes #4542
This commit is contained in:
Alex Lam S.L
2021-01-12 04:07:01 +00:00
committed by GitHub
parent 1e831df1f6
commit b689028e87
2 changed files with 89 additions and 1 deletions

View File

@@ -9390,7 +9390,8 @@ merge(Compressor.prototype, {
|| self.right.left.is_number(compressor))
&& (self.operator != "-" || !self.left.is_negative_zero())
&& (self.right.left.is_constant_expression()
|| !self.right.right.has_side_effects(compressor))) {
|| !self.right.right.has_side_effects(compressor))
&& !is_modify_array(self.right.right)) {
self = make_node(AST_Binary, self, {
operator: align(self.operator, self.right.operator),
left: make_node(AST_Binary, self.left, {
@@ -9534,6 +9535,21 @@ merge(Compressor.prototype, {
}
return try_evaluate(compressor, self);
function is_modify_array(node) {
var found = false;
node.walk(new TreeWalker(function(node) {
if (found) return true;
if (node instanceof AST_Assign) {
if (node.left instanceof AST_PropAccess) return found = true;
} else if (node instanceof AST_Unary) {
if (unary_side_effects[node.operator] && node.expression instanceof AST_PropAccess) {
return found = true;
}
}
}));
return found;
}
function align(ref, op) {
switch (ref) {
case "-":

View File

@@ -1386,3 +1386,75 @@ issue_4142: {
}
expect_stdout: "0"
}
issue_4542_1: {
options = {
evaluate: true,
unsafe_math: true,
}
input: {
console.log(function(a) {
return a / (1 / (a[0] = 2));
}([ 3 ]));
}
expect: {
console.log(function(a) {
return a / (1 / (a[0] = 2));
}([ 3 ]));
}
expect_stdout: "4"
}
issue_4542_2: {
options = {
evaluate: true,
unsafe_math: true,
}
input: {
console.log(function(a) {
return a / (1 / --a[0]);
}([ 3 ]));
}
expect: {
console.log(function(a) {
return a / (1 / --a[0]);
}([ 3 ]));
}
expect_stdout: "4"
}
issue_4542_3: {
options = {
evaluate: true,
unsafe_math: true,
}
input: {
console.log(function(a) {
return a / (0 / (a[0] = 0, 1));
}([ 1 ]));
}
expect: {
console.log(function(a) {
return a / (0 / (a[0] = 0, 1));
}([ 1 ]));
}
expect_stdout: "NaN"
}
issue_4542_4: {
options = {
evaluate: true,
unsafe_math: true,
}
input: {
console.log(function(a) {
return a / (1 / (a.length = 1));
}([ 2, 3 ]));
}
expect: {
console.log(function(a) {
return a / (1 / (a.length = 1));
}([ 2, 3 ]));
}
expect_stdout: "2"
}