Fixes a bad optimization that completely pruned empty try blocks, even if they had non-empty finally blocks that needed to be run.

Found by: knorton
Patch by: alex.tkachman (+scottb)
Review by: mmendez (desk check), scottb


git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@1004 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/DeadCodeElimination.java b/dev/core/src/com/google/gwt/dev/jjs/impl/DeadCodeElimination.java
index 7863f74..742c87a 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/DeadCodeElimination.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/DeadCodeElimination.java
@@ -343,14 +343,19 @@
       }
 
       // Compute properties regarding the state of this try statement
-      boolean noTry = x.getTryBlock().statements.isEmpty();
-      // TODO: normalize finally block handling
-      boolean noFinally = isEmpty(x.getFinallyBlock());
+      boolean noTry = isEmpty(x.getTryBlock());
       boolean noCatch = catchArgs.size() == 0;
+      boolean noFinally = isEmpty(x.getFinallyBlock());
 
       if (noTry) {
         // 2) Prune try statements with no body.
-        removeMe(x, ctx);
+        if (noFinally) {
+          // if there's no finally, prune the whole thing
+          removeMe(x, ctx);
+        } else {
+          // replace the try statement with just the contents of the finally
+          ctx.replaceMe(x.getFinallyBlock());
+        }
       } else if (noCatch && noFinally) {
         // 3) Hoist up try statements with no catches and an empty finally.
         // If there's no catch or finally, there's no point in this even being
diff --git a/user/test/com/google/gwt/dev/jjs/test/CompilerTest.java b/user/test/com/google/gwt/dev/jjs/test/CompilerTest.java
index 21466f8..dac5929 100644
--- a/user/test/com/google/gwt/dev/jjs/test/CompilerTest.java
+++ b/user/test/com/google/gwt/dev/jjs/test/CompilerTest.java
@@ -407,6 +407,15 @@
       ;
   }-*/;
 
+  public void testEmptyTryBlock() {
+    int x = 0;
+    try {
+    } finally {
+      x = 1;
+    }
+    assertEquals(1, x);
+  }
+
   public void testForStatement() {
     {
       int i;
@@ -452,7 +461,7 @@
       assertTrue(delete);
     }
   }
-  
+
   public void testLabels() {
     int i = 0, j = 0;
     outer : for (i = 0; i < 1; ++i) {
@@ -504,7 +513,7 @@
     };
     assertEquals(1, i);
   }
-  
+
   public void testLocalRefs() {
     final String foo = noOptimizeTrue() ? "foo" : "bar";
     final String bar = noOptimizeTrue() ? "bar" : "foo";
@@ -638,7 +647,7 @@
     assertEquals(new Foo(1).i, 1);
     assertEquals(new Foo(2).i, 2);
   }
-  
+
   public void testStringOptimizations() {
     assertEquals("Herro, AJAX", "Hello, AJAX".replace('l', 'r'));
     assertEquals('J', "Hello, AJAX".charAt(8));