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