fix corner case in `side_effects` (#4226)
authorAlex Lam S.L <alexlamsl@gmail.com>
Sun, 18 Oct 2020 14:13:10 +0000 (15:13 +0100)
committerGitHub <noreply@github.com>
Sun, 18 Oct 2020 14:13:10 +0000 (22:13 +0800)
fixes #4225

lib/compress.js
test/compress/const.js

index 504bf39..015ee30 100644 (file)
@@ -5881,24 +5881,31 @@ merge(Compressor.prototype, {
             if (!property) return expression;
             return make_sequence(this, [ expression, property ]);
         });
-        def(AST_SymbolRef, function(compressor) {
-            return this.is_declared(compressor) && all(this.definition().orig, function(sym) {
+        function drop_symbol(ref) {
+            return all(ref.definition().orig, function(sym) {
                 return !(sym instanceof AST_SymbolConst);
-            }) ? null : this;
+            });
+        }
+        def(AST_SymbolRef, function(compressor) {
+            return this.is_declared(compressor) && drop_symbol(this) ? null : this;
         });
         def(AST_This, return_null);
         def(AST_Unary, function(compressor, first_in_statement) {
+            var exp = this.expression;
             if (unary_side_effects[this.operator]) {
-                this.write_only = !this.expression.has_side_effects(compressor);
+                this.write_only = !exp.has_side_effects(compressor);
                 return this;
             }
-            if (this.operator == "typeof" && this.expression instanceof AST_SymbolRef) return null;
-            var expression = this.expression.drop_side_effect_free(compressor, first_in_statement);
-            if (first_in_statement && expression && is_iife_call(expression)) {
-                if (expression === this.expression && this.operator == "!") return this;
-                return expression.negate(compressor, first_in_statement);
+            if (this.operator == "typeof" && exp instanceof AST_SymbolRef) {
+                if (drop_symbol(exp)) return null;
+                if (exp.is_declared(compressor)) return exp;
             }
-            return expression;
+            var node = exp.drop_side_effect_free(compressor, first_in_statement);
+            if (first_in_statement && node && is_iife_call(node)) {
+                if (node === exp && this.operator == "!") return this;
+                return node.negate(compressor, first_in_statement);
+            }
+            return node;
         });
     })(function(node, func) {
         node.DEFMETHOD("drop_side_effect_free", func);
index ef5c967..3e6662c 100644 (file)
@@ -1134,3 +1134,20 @@ issue_4222: {
     }
     expect_stdout: true
 }
+
+issue_4225: {
+    options = {
+        side_effects: true,
+    }
+    input: {
+        const a = void typeof b;
+        const b = 42;
+        console.log(a, b);
+    }
+    expect: {
+        const a = void b;
+        const b = 42;
+        console.log(a, b);
+    }
+    expect_stdout: true
+}