Fixes a bug where Simplifier.conditional() could recurse back into
itself and cause an NPE. It should actually tolerate null as the
first argument.
Review by: scottb
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@5070 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/Simplifier.java b/dev/core/src/com/google/gwt/dev/jjs/impl/Simplifier.java
index f103083..aa7f3fc 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/Simplifier.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/Simplifier.java
@@ -145,17 +145,15 @@
} else if (thenExpr instanceof JBooleanLiteral) {
if (((JBooleanLiteral) thenExpr).getValue()) {
// e.g. (cond ? true : else) -> cond || else
- JBinaryOperation binOp = new JBinaryOperation(program,
- original.getSourceInfo(), original.getType(), JBinaryOperator.OR,
- condExpr, elseExpr);
+ JBinaryOperation binOp = new JBinaryOperation(program, sourceInfo,
+ type, JBinaryOperator.OR, condExpr, elseExpr);
return binOp;
} else {
// e.g. (cond ? false : else) -> !cond && else
JPrefixOperation notCondExpr = new JPrefixOperation(program,
condExpr.getSourceInfo(), JUnaryOperator.NOT, condExpr);
- JBinaryOperation binOp = new JBinaryOperation(program,
- original.getSourceInfo(), original.getType(), JBinaryOperator.AND,
- notCondExpr, elseExpr);
+ JBinaryOperation binOp = new JBinaryOperation(program, sourceInfo,
+ type, JBinaryOperator.AND, notCondExpr, elseExpr);
return binOp;
}
} else if (elseExpr instanceof JBooleanLiteral) {
@@ -163,23 +161,21 @@
// e.g. (cond ? then : true) -> !cond || then
JPrefixOperation notCondExpr = new JPrefixOperation(program,
condExpr.getSourceInfo(), JUnaryOperator.NOT, condExpr);
- JBinaryOperation binOp = new JBinaryOperation(program,
- original.getSourceInfo(), original.getType(), JBinaryOperator.OR,
- notCondExpr, thenExpr);
+ JBinaryOperation binOp = new JBinaryOperation(program, sourceInfo,
+ type, JBinaryOperator.OR, notCondExpr, thenExpr);
return binOp;
} else {
// e.g. (cond ? then : false) -> cond && then
- JBinaryOperation binOp = new JBinaryOperation(program,
- original.getSourceInfo(), original.getType(), JBinaryOperator.AND,
- condExpr, thenExpr);
+ JBinaryOperation binOp = new JBinaryOperation(program, sourceInfo,
+ type, JBinaryOperator.AND, condExpr, thenExpr);
return binOp;
}
} else {
// e.g. (!cond ? then : else) -> (cond ? else : then)
JExpression unflipped = maybeUnflipBoolean(condExpr);
if (unflipped != null) {
- return new JConditional(program, original.getSourceInfo(),
- original.getType(), unflipped, elseExpr, thenExpr);
+ return new JConditional(program, sourceInfo, type, unflipped, elseExpr,
+ thenExpr);
}
}
diff --git a/user/test/com/google/gwt/dev/jjs/test/JStaticEvalTest.java b/user/test/com/google/gwt/dev/jjs/test/JStaticEvalTest.java
index e445b15..e96578a 100644
--- a/user/test/com/google/gwt/dev/jjs/test/JStaticEvalTest.java
+++ b/user/test/com/google/gwt/dev/jjs/test/JStaticEvalTest.java
@@ -36,6 +36,7 @@
}
private volatile double fieldDoubleFive = 5.0;
+ private volatile boolean fieldFalse = false;
private volatile float fieldFloatFive = 5.0F;
private volatile int[] fieldIntArray = new int[10];
private volatile int fieldIntFive = 5;
@@ -49,6 +50,31 @@
}
/**
+ * Tests simplifications on ternary conditional expressions.
+ */
+ public void testConditionalExpressions() {
+ assertEquals(1, returnTrue() ? 1 : 2);
+ assertEquals(2, returnFalse() ? 1 : 2);
+ assertEquals(true, fieldTrue ? true : fieldFalse);
+ assertEquals(false, fieldTrue ? false : fieldTrue);
+ assertEquals(true, fieldTrue ? fieldTrue : false);
+ assertEquals(false, fieldTrue ? fieldFalse : true);
+ assertEquals(2, !fieldTrue ? 1 : 2);
+ assertEquals(2, !fieldTrue ? 1 : 2);
+
+ /*
+ * This example causes Simplifier to recurse into itself, which in previous
+ * versions could cause a NullPointerException. The sequence of
+ * simplifications is:
+ */
+ // (fieldFalse = false, !fieldFalse) ? 1 : 2 // inlining
+ // (fieldFalse = false, !fieldfalse ? 1 : 2) // move multi outward
+ // (fieldFalse = false, fieldFalse ? 2 : 1) // flip negative condition
+ int res = doSomethingAndReturnTrue() ? 1 : 2;
+ assertEquals(1, res);
+ }
+
+ /**
* Test "true == booleanField" and permutations, as well as "true == false"
* and permutations.
*/
@@ -278,6 +304,14 @@
}
}
+ /**
+ * This method will inline as a multi.
+ */
+ private boolean doSomethingAndReturnTrue() {
+ fieldTrue = true;
+ return !fieldFalse;
+ }
+
// All of these returnFoo() methods exist so that the
// JDT will not be able to statically evaluate with
// the returned values. These simple methods will be