fix corner case in `evaluate` (#4120)
authorAlex Lam S.L <alexlamsl@gmail.com>
Thu, 17 Sep 2020 13:20:31 +0000 (14:20 +0100)
committerGitHub <noreply@github.com>
Thu, 17 Sep 2020 13:20:31 +0000 (21:20 +0800)
fixes #4119

lib/compress.js
test/compress/evaluate.js

index 76be475..f59cc4d 100644 (file)
@@ -3362,6 +3362,7 @@ merge(Compressor.prototype, {
             cached.forEach(function(node) {
                 delete node._eval;
             });
+            if (cached.unsafe) return this;
             if (ignore_side_effects) return val;
             if (!val || val instanceof RegExp) return val;
             if (typeof val == "function" || typeof val == "object") return this;
@@ -3430,6 +3431,10 @@ merge(Compressor.prototype, {
             var value = node._eval(compressor, ignore_side_effects, cached, depth);
             if (value === node) return this;
             modified(lhs);
+            if (Array.isArray(value)) value.toString = function() {
+                cached.unsafe = true;
+                return "[]";
+            };
             return value;
         });
         def(AST_Sequence, function(compressor, ignore_side_effects, cached, depth) {
index 6d4d084..5cf3fb1 100644 (file)
@@ -2908,3 +2908,55 @@ issue_4077: {
     }
     expect_stdout: "PASS"
 }
+
+issue_4119_1: {
+    options = {
+        conditionals: true,
+        dead_code: true,
+        evaluate: true,
+        reduce_vars: true,
+        toplevel: true,
+        unsafe: true,
+    }
+    input: {
+        var a, b;
+        b = a = [];
+        a[0] += 0;
+        if (+b + 1) {
+            console.log("FAIL");
+        } else {
+            console.log("PASS");
+        }
+    }
+    expect: {
+        var a, b;
+        b = a = [];
+        a[0] += 0;
+        +b + 1 ? console.log("FAIL") : console.log("PASS");
+    }
+    expect_stdout: "PASS"
+}
+
+issue_4119_2: {
+    options = {
+        conditionals: true,
+        evaluate: true,
+        reduce_vars: true,
+        unsafe: true,
+    }
+    input: {
+        var a;
+        (function(b) {
+            a[0] += 0;
+            console.log(+b + 1 ? "FAIL" : "PASS");
+        })(a = []);
+    }
+    expect: {
+        var a;
+        (function(b) {
+            a[0] += 0;
+            console.log(+b + 1 ? "FAIL" : "PASS");
+        })(a = []);
+    }
+    expect_stdout: "PASS"
+}