fix `dead_code` on exceptional `return` (#2930)
authorAlex Lam S.L <alexlamsl@gmail.com>
Sat, 17 Feb 2018 20:36:00 +0000 (04:36 +0800)
committerGitHub <noreply@github.com>
Sat, 17 Feb 2018 20:36:00 +0000 (04:36 +0800)
fixes #2929

lib/compress.js
test/compress/dead-code.js

index f8e9f91..2cc8282 100644 (file)
@@ -2863,6 +2863,9 @@ merge(Compressor.prototype, {
         def(AST_ObjectProperty, function(compressor){
             return this.value.may_throw(compressor);
         });
+        def(AST_Return, function(compressor){
+            return this.value.may_throw(compressor);
+        });
         def(AST_Sequence, function(compressor){
             return any(this.expressions, compressor);
         });
@@ -2882,8 +2885,7 @@ merge(Compressor.prototype, {
             return !this.is_declared(compressor);
         });
         def(AST_Try, function(compressor){
-            return any(this.body, compressor)
-                || this.bcatch && this.bcatch.may_throw(compressor)
+            return this.bcatch ? this.bcatch.may_throw(compressor) : any(this.body, compressor)
                 || this.bfinally && this.bfinally.may_throw(compressor);
         });
         def(AST_Unary, function(compressor){
@@ -5511,7 +5513,7 @@ merge(Compressor.prototype, {
                 node = parent;
                 parent = compressor.parent(level++);
                 if (parent instanceof AST_Exit) {
-                    if (in_try(level, parent instanceof AST_Throw)) break;
+                    if (in_try(level, parent)) break;
                     if (is_reachable(def.scope, [ def ])) break;
                     if (self.operator == "=") return self.right;
                     def.fixed = false;
@@ -5545,13 +5547,17 @@ merge(Compressor.prototype, {
         }
         return self;
 
-        function in_try(level, no_catch) {
+        function in_try(level, node) {
+            var right = self.right;
+            self.right = make_node(AST_Null, right);
+            var may_throw = node.may_throw(compressor);
+            self.right = right;
             var scope = self.left.definition().scope;
             var parent;
             while ((parent = compressor.parent(level++)) !== scope) {
                 if (parent instanceof AST_Try) {
                     if (parent.bfinally) return true;
-                    if (no_catch && parent.bcatch) return true;
+                    if (may_throw && parent.bcatch) return true;
                 }
             }
         }
index 9b45fe8..41f5842 100644 (file)
@@ -917,3 +917,28 @@ issue_2860_2: {
     }
     expect_stdout: "1"
 }
+
+issue_2929: {
+    options = {
+        dead_code: true,
+    }
+    input: {
+        console.log(function(a) {
+            try {
+                return null.p = a = 1;
+            } catch (e) {
+                return a ? "PASS" : "FAIL";
+            }
+        }());
+    }
+    expect: {
+        console.log(function(a) {
+            try {
+                return null.p = a = 1;
+            } catch (e) {
+                return a ? "PASS" : "FAIL";
+            }
+        }());
+    }
+    expect_stdout: "PASS"
+}