Cherrypick r11332 into 2.5 release branch
Fix for Issue tracker issue #5739
Review by: rdayal@google.com
git-svn-id: https://google-web-toolkit.googlecode.com/svn/releases/2.5@11341 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/gflow/cfg/CfgBuilder.java b/dev/core/src/com/google/gwt/dev/jjs/impl/gflow/cfg/CfgBuilder.java
index aeb0cf7..2de8465 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/gflow/cfg/CfgBuilder.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/gflow/cfg/CfgBuilder.java
@@ -22,6 +22,7 @@
import com.google.gwt.dev.jjs.ast.JBlock;
import com.google.gwt.dev.jjs.ast.JBreakStatement;
import com.google.gwt.dev.jjs.ast.JCaseStatement;
+import com.google.gwt.dev.jjs.ast.JCastOperation;
import com.google.gwt.dev.jjs.ast.JClassType;
import com.google.gwt.dev.jjs.ast.JConditional;
import com.google.gwt.dev.jjs.ast.JContinueStatement;
@@ -35,6 +36,7 @@
import com.google.gwt.dev.jjs.ast.JIfStatement;
import com.google.gwt.dev.jjs.ast.JLabeledStatement;
import com.google.gwt.dev.jjs.ast.JMethodCall;
+import com.google.gwt.dev.jjs.ast.JNode;
import com.google.gwt.dev.jjs.ast.JProgram;
import com.google.gwt.dev.jjs.ast.JReboundEntryPoint;
import com.google.gwt.dev.jjs.ast.JReturnStatement;
@@ -406,6 +408,26 @@
return false;
}
+ /**
+ * Each cast operation generates optional throw.
+ * Fixes http://code.google.com/p/google-web-toolkit/issues/detail?id=5739
+ */
+ @Override
+ public boolean visit(JCastOperation x, Context ctx) {
+ accept(x.getExpr());
+
+ CfgOptionalThrowNode node = addNode(new CfgOptionalThrowNode(parent, x));
+ addNormalExit(node, CfgOptionalThrowNode.NO_THROW);
+ JDeclaredType runtimeExceptionType =
+ program.getFromTypeMap("java.lang.RuntimeException");
+ if (runtimeExceptionType != null) {
+ addExit(Exit.createThrow(node, runtimeExceptionType,
+ CfgOptionalThrowNode.RUNTIME_EXCEPTION));
+ }
+ addNode(new CfgCastOperationNode(parent, x));
+ return false;
+ }
+
@Override
public boolean visit(JConditional x, Context ctx) {
accept(x.getIfTest());
@@ -1186,6 +1208,23 @@
}
}
+ private static class CfgCastOperationNode extends CfgSimpleNode<JNode> {
+
+ public CfgCastOperationNode(CfgNode<?> parent, JNode jNode) {
+ super(parent, jNode);
+ }
+
+ @Override
+ public void accept(CfgVisitor visitor) {
+ visitor.visitSimpleNode(this);
+ }
+
+ @Override
+ protected CfgNode<?> cloneImpl() {
+ return new CfgCastOperationNode(getParent(), getJNode());
+ }
+ }
+
/**
* Special exception which is thrown when we encounter some syntactic
* construction which is not yet supported by CfgBuilder.
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/gflow/cfg/CfgOptionalThrowNode.java b/dev/core/src/com/google/gwt/dev/jjs/impl/gflow/cfg/CfgOptionalThrowNode.java
index 3c52d0f..33a0372 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/gflow/cfg/CfgOptionalThrowNode.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/gflow/cfg/CfgOptionalThrowNode.java
@@ -15,12 +15,13 @@
*/
package com.google.gwt.dev.jjs.impl.gflow.cfg;
+import com.google.gwt.dev.jjs.ast.JExpression;
import com.google.gwt.dev.jjs.ast.JMethodCall;
/**
* Node which might throw exception.
*/
-public class CfgOptionalThrowNode extends CfgNode<JMethodCall> {
+public class CfgOptionalThrowNode extends CfgNode<JExpression> {
/**
* Edge role for normal, no-throwing execution.
*/
@@ -34,7 +35,7 @@
*/
public static final String ERROR = "E";
- public CfgOptionalThrowNode(CfgNode<?> parent, JMethodCall node) {
+ public CfgOptionalThrowNode(CfgNode<?> parent, JExpression node) {
super(parent, node);
}
@@ -45,7 +46,10 @@
@Override
public String toDebugString() {
- return "OPTTHROW(" + getJNode().getTarget().getName() + "())";
+ if (getJNode() instanceof JMethodCall) {
+ return "OPTTHROW(" + ((JMethodCall) getJNode()).getTarget().getName() + "())";
+ }
+ return "OPTTHROW(" + getJNode().toSource() + ")";
}
@Override
diff --git a/dev/core/test/com/google/gwt/dev/jjs/impl/gflow/DataflowOptimizerTest.java b/dev/core/test/com/google/gwt/dev/jjs/impl/gflow/DataflowOptimizerTest.java
index 60a1a00..9ee6e0d 100644
--- a/dev/core/test/com/google/gwt/dev/jjs/impl/gflow/DataflowOptimizerTest.java
+++ b/dev/core/test/com/google/gwt/dev/jjs/impl/gflow/DataflowOptimizerTest.java
@@ -301,6 +301,35 @@
);
}
+ /**
+ * Test fix for http://code.google.com/p/google-web-toolkit/issues/detail?id=5739
+ */
+ public void testExceptionInitializerFlow() throws Exception {
+ addSnippetClassDecl("static int foo() { return 0; }");
+ optimize("boolean", " int size = -1;\n" +
+ " try {\n" +
+ " size = ((Object[]) (Object)\"aaa\").length;\n" +
+ " } catch (final Exception ex) {\n" +
+ " }\n" +
+ " if (size < 0) {\n" +
+ " try {\n" +
+ " size = 3;\n" +
+ " } catch (final Exception ex) {\n" +
+ " }\n" +
+ " }\n" +
+ " return size > 0;").into("int size = -1;\n" +
+ " try {\n" +
+ " size = ((Object[]) (Object)\"aaa\").length;\n" +
+ " } catch (final Exception ex) {\n" +
+ " }\n" +
+ " if (size < 0) {\n" +
+ " try {\n" +
+ " size = 3;\n" +
+ " } catch (final Exception ex) {\n" +
+ " }\n" +
+ " } return size > 0;");
+ }
+
public void testImplicitConversion() throws Exception {
optimize("long",
"int bar = 0x12345678;",