fix corner case in `unsafe_math` (#3548)
authorAlex Lam S.L <alexlamsl@gmail.com>
Tue, 29 Oct 2019 09:06:57 +0000 (17:06 +0800)
committerGitHub <noreply@github.com>
Tue, 29 Oct 2019 09:06:57 +0000 (17:06 +0800)
fixes #3547

lib/compress.js
test/compress/numbers.js

index 3058b67..d37108d 100644 (file)
@@ -6024,9 +6024,12 @@ merge(Compressor.prototype, {
                 if (self.right instanceof AST_Constant
                     && self.left instanceof AST_Binary
                     && self.left.operator != "%"
-                    && PRECEDENCE[self.left.operator] == PRECEDENCE[self.operator]) {
+                    && PRECEDENCE[self.left.operator] == PRECEDENCE[self.operator]
+                    && self.left.is_number(compressor)) {
                     if (self.left.left instanceof AST_Constant
-                        && (self.left.operator != "+" || self.left.right.is_number(compressor))) {
+                        && (self.operator != "+"
+                            || self.left.left.is_boolean(compressor)
+                            || self.left.left.is_number(compressor))) {
                         self = make_node(AST_Binary, self, {
                             operator: self.left.operator,
                             left: make_node(AST_Binary, self.left, {
@@ -6038,19 +6041,23 @@ merge(Compressor.prototype, {
                             }),
                             right: self.left.right
                         });
-                    } else if (self.left.right instanceof AST_Constant
-                        && (self.left.operator != "+" || self.left.left.is_number(compressor))) {
-                        self = make_node(AST_Binary, self, {
-                            operator: self.left.operator,
-                            left: self.left.left,
-                            right: make_node(AST_Binary, self.left, {
-                                operator: align(self.left.operator, self.operator),
-                                left: self.left.right,
-                                right: self.right,
-                                start: self.left.right.start,
-                                end: self.right.end
-                            })
-                        });
+                    } else if (self.left.right instanceof AST_Constant) {
+                        var op = align(self.left.operator, self.operator);
+                        if (op != "+"
+                            || self.left.right.is_boolean(compressor)
+                            || self.left.right.is_number(compressor)) {
+                            self = make_node(AST_Binary, self, {
+                                operator: self.left.operator,
+                                left: self.left.left,
+                                right: make_node(AST_Binary, self.left, {
+                                    operator: op,
+                                    left: self.left.right,
+                                    right: self.right,
+                                    start: self.left.right.start,
+                                    end: self.right.end
+                                })
+                            });
+                        }
                     }
                 }
                 break;
index 79fccfb..cbb2863 100644 (file)
@@ -781,3 +781,139 @@ issue_3539: {
     }
     expect_stdout: "NaN -Infinity Infinity"
 }
+
+issue_3547_1: {
+    options = {
+        evaluate: true,
+        unsafe_math: true,
+    }
+    input: {
+        [
+            1/0 + "1" + 0,
+            1/0 + "1" - 0,
+            1/0 - "1" + 0,
+            1/0 - "1" - 0,
+        ].forEach(function(n) {
+            console.log(typeof n, n);
+        });
+    }
+    expect: {
+        [
+            1/0 + "10",
+            NaN,
+            1/0,
+            1/0,
+        ].forEach(function(n) {
+            console.log(typeof n, n);
+        });
+    }
+    expect_stdout: [
+        "string Infinity10",
+        "number NaN",
+        "number Infinity",
+        "number Infinity",
+    ]
+}
+
+issue_3547_2: {
+    options = {
+        evaluate: true,
+        unsafe_math: true,
+    }
+    input: {
+        [
+            "1" + 1/0 + 0,
+            "1" + 1/0 - 0,
+            "1" - 1/0 + 0,
+            "1" - 1/0 - 0,
+        ].forEach(function(n) {
+            console.log(typeof n, n);
+        });
+    }
+    expect: {
+        [
+            "1" + 1/0 + 0,
+            NaN,
+            -1/0,
+            -1/0,
+        ].forEach(function(n) {
+            console.log(typeof n, n);
+        });
+    }
+    expect_stdout: [
+        "string 1Infinity0",
+        "number NaN",
+        "number -Infinity",
+        "number -Infinity",
+    ]
+}
+
+issue_3547_3: {
+    options = {
+        evaluate: true,
+        unsafe_math: true,
+    }
+    input: {
+        var a = "3";
+        [
+            a + "2" + 1,
+            a + "2" - 1,
+            a - "2" + 1,
+            a - "2" - 1,
+        ].forEach(function(n) {
+            console.log(typeof n, n);
+        });
+    }
+    expect: {
+        var a = "3";
+        [
+            a + "21",
+            a + "2" - 1,
+            a - 1,
+            a - "2" - 1,
+        ].forEach(function(n) {
+            console.log(typeof n, n);
+        });
+    }
+    expect_stdout: [
+        "string 321",
+        "number 31",
+        "number 2",
+        "number 0",
+    ]
+}
+
+issue_3547_4: {
+    options = {
+        evaluate: true,
+        unsafe_math: true,
+    }
+    input: {
+        var a = "2";
+        [
+            "3" + a + 1,
+            "3" + a - 1,
+            "3" - a + 1,
+            "3" - a - 1,
+        ].forEach(function(n) {
+            console.log(typeof n, n);
+        });
+    }
+    expect: {
+        var a = "2";
+        [
+            "3" + a + 1,
+            "3" + a - 1,
+            "3" - a + 1,
+            2 - a,
+        ].forEach(function(n) {
+            console.log(typeof n, n);
+        });
+    }
+    expect_stdout: [
+        "string 321",
+        "number 31",
+        "number 2",
+        "number 0",
+    ]
+}