fix corner case in `unsafe` `evaluate` (#3989)
authorAlex Lam S.L <alexlamsl@gmail.com>
Wed, 10 Jun 2020 23:37:39 +0000 (00:37 +0100)
committerGitHub <noreply@github.com>
Wed, 10 Jun 2020 23:37:39 +0000 (07:37 +0800)
fixes #3988

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

index 0eaa3a4..8d8dffa 100644 (file)
@@ -3562,32 +3562,32 @@ merge(Compressor.prototype, {
         var regexp_props = makePredicate("global ignoreCase multiline source");
         def(AST_PropAccess, function(compressor, ignore_side_effects, cached, depth) {
             if (compressor.option("unsafe")) {
+                var val;
+                var exp = this.expression;
+                if (!is_undeclared_ref(exp)) {
+                    val = exp._eval(compressor, ignore_side_effects, cached, depth + 1);
+                    if (val == null || val === exp) return this;
+                }
                 var key = this.property;
                 if (key instanceof AST_Node) {
                     key = key._eval(compressor, ignore_side_effects, cached, depth);
                     if (key === this.property) return this;
                 }
-                var exp = this.expression;
-                var val;
-                if (is_undeclared_ref(exp)) {
+                if (val === undefined) {
                     var static_value = static_values[exp.name];
                     if (!static_value || !static_value[key]) return this;
                     val = global_objs[exp.name];
-                } else {
-                    val = exp._eval(compressor, ignore_side_effects, cached, depth + 1);
-                    if (val == null || val === exp) return this;
-                    if (val instanceof RegExp) {
-                        if (!regexp_props[key]) return this;
-                    } else if (typeof val == "object") {
-                        if (!HOP(val, key)) return this;
-                    } else if (typeof val == "function") switch (key) {
-                      case "name":
-                        return val.node.name ? val.node.name.name : "";
-                      case "length":
-                        return val.node.argnames.length;
-                      default:
-                        return this;
-                    }
+                } else if (val instanceof RegExp) {
+                    if (!regexp_props[key]) return this;
+                } else if (typeof val == "object") {
+                    if (!HOP(val, key)) return this;
+                } else if (typeof val == "function") switch (key) {
+                  case "name":
+                    return val.node.name ? val.node.name.name : "";
+                  case "length":
+                    return val.node.argnames.length;
+                  default:
+                    return this;
                 }
                 return val[key];
             }
index 0f3a9fd..da928b3 100644 (file)
@@ -2735,3 +2735,27 @@ issue_3953: {
     }
     expect_stdout: "PASS"
 }
+
+issue_3988: {
+    options = {
+        evaluate: true,
+        reduce_vars: true,
+        toplevel: true,
+        unsafe: true,
+        unused: true,
+    }
+    input: {
+        function f(b) {
+            return ("" + (b &= 0))[b && this];
+        }
+        var a = f();
+        console.log(a);
+    }
+    expect: {
+        var a = function(b) {
+            return ("" + (b &= 0))[b && this];
+        }();
+        console.log(a);
+    }
+    expect_stdout: "0"
+}