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) {