aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Lam S.L <alexlamsl@gmail.com>2020-01-28 22:44:18 +0800
committerGitHub <noreply@github.com>2020-01-28 22:44:18 +0800
commit87119e44a08118bf302a4da6ae71e74f8bea4f89 (patch)
tree9907c467959cf510bcae59126996485e3c212cbd
parentb499e03f82987d59814c81fb9f211fee5e3a7ba4 (diff)
downloadtracifyjs-87119e44a08118bf302a4da6ae71e74f8bea4f89.tar.gz
tracifyjs-87119e44a08118bf302a4da6ae71e74f8bea4f89.zip
fix corner case in sign propagation (#3696)
- migrate de-facto functionality to `evaluate` fixes #3695
-rw-r--r--lib/compress.js19
-rw-r--r--test/compress/issue-1770.js2
-rw-r--r--test/compress/numbers.js18
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"
+}