Disables constant folding in two cases where a division by zero could result. 

Review by: scottb (TBR)


git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@3283 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 5de3ae9..98a537a 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
@@ -824,9 +824,17 @@
                 res = left * right;
                 break;
               case DIV:
+                if (right == 0) {
+                  // Don't divide by zero
+                  return false;
+                }
                 res = left / right;
                 break;
               case MOD:
+                if (right == 0) {
+                  // Don't divide by zero
+                  return false;
+                }
                 res = left % right;
                 break;
               default:
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 74a017b..7eb613b 100644
--- a/user/test/com/google/gwt/dev/jjs/test/CompilerTest.java
+++ b/user/test/com/google/gwt/dev/jjs/test/CompilerTest.java
@@ -147,8 +147,9 @@
 
   private static volatile boolean TRUE = true;
 
-  private static volatile int volatileInt;
   private static volatile boolean volatileBoolean;
+  private static volatile int volatileInt;
+  private static volatile long volatileLong;
   private static volatile UninstantiableType volatileUninstantiableType;
 
   private static native void accessUninstantiableField(UninstantiableType u) /*-{
@@ -355,6 +356,46 @@
     }
   }
 
+  /**
+   * Make sure that the compiler does not crash itself on user code that divides
+   * by zero. The actual behavior varies by the numeric type and whether it is
+   * hosted mode or web mode, but the important thing is that the compiler does
+   * not crash.
+   */
+  public void testDivByZero() {
+    assertTrue(Double.isNaN(0.0 / 0.0));
+
+    try {
+      // 0 / 0 is currently 0 in web mode.
+      assertEquals(0, 0 / 0);
+    } catch (ArithmeticException expected) {
+      // expected in hosted mode
+    }
+
+    try {
+      volatileLong = 0L / 0;
+      fail("expected an ArithmeticException");
+    } catch (ArithmeticException expected) {
+      // expected
+    }
+
+    assertTrue(Double.isNaN(0.0 % 0.0));
+
+    try {
+      // 0 % 0 is currently NaN in web mode.
+      assertTrue(Double.isNaN(0 % 0));
+    } catch (ArithmeticException expected) {
+      // expected in hosted mode
+    }
+
+    try {
+      volatileLong = 0L % 0;
+      fail("expected an ArithmeticException");
+    } catch (ArithmeticException expected) {
+      // expected
+    }
+  }
+
   public void testEmptyBlockStatements() {
     boolean b = false;
     while (b) {