Don't allow constants folding and copy propagation optimizations to perform implicit type conversions.

Review by: rice@google.com

git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@9959 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/gflow/constants/ConstantsFlowFunction.java b/dev/core/src/com/google/gwt/dev/jjs/impl/gflow/constants/ConstantsFlowFunction.java
index 32bcd22..17ec67e 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/gflow/constants/ConstantsFlowFunction.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/gflow/constants/ConstantsFlowFunction.java
@@ -18,6 +18,7 @@
 import com.google.gwt.dev.jjs.ast.JBooleanLiteral;
 import com.google.gwt.dev.jjs.ast.JExpression;
 import com.google.gwt.dev.jjs.ast.JLocal;
+import com.google.gwt.dev.jjs.ast.JNullLiteral;
 import com.google.gwt.dev.jjs.ast.JParameter;
 import com.google.gwt.dev.jjs.ast.JValueLiteral;
 import com.google.gwt.dev.jjs.ast.JVariable;
@@ -106,7 +107,14 @@
           if (expression != null) {
             JValueLiteral valueLiteral = 
               ExpressionEvaluator.evaluate(expression, assumption.unwrap());
-            assumption.set(var, valueLiteral);
+            if (valueLiteral != null && 
+                (valueLiteral.getType() == var.getType() || 
+                 valueLiteral instanceof JNullLiteral)) {
+              assumption.set(var, valueLiteral);
+            } else {
+              // Don't bother to try to get conversions right.
+              assumption.set(var, null);
+            }
           } else {
             assumption.set(var, null);
           }
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/gflow/copy/CopyFlowFunction.java b/dev/core/src/com/google/gwt/dev/jjs/impl/gflow/copy/CopyFlowFunction.java
index 4257b00..3c0be2b 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/gflow/copy/CopyFlowFunction.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/gflow/copy/CopyFlowFunction.java
@@ -66,7 +66,8 @@
         
         if (original != targetVariable) {
           result.kill(targetVariable);
-          if (isSupportedVar(original)) {
+          if (isSupportedVar(original) && 
+              original.getType() == targetVariable.getType()) {
             result.addCopy(original, targetVariable);
           }
         } else {
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 26f11da..ef88dd3 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
@@ -262,6 +262,20 @@
        );
   }
 
+  public void testImplicitConversion() throws Exception {
+    optimize("long", 
+        "int bar = 0x12345678;",
+        "bar = bar * 1234;",
+        "long lng = bar;",
+        "long lng8 = lng << 8;",
+        "return lng8;"
+        ).into(
+            "  int bar;", 
+            "  long lng = -1068970384;", 
+            "  long lng8 = lng << 8;", 
+            "  return lng8;");
+  }
+
   @Override
   protected boolean optimizeMethod(JProgram program, JMethod method) {
     return DataflowOptimizer.exec(program, method).didChange();
diff --git a/dev/core/test/com/google/gwt/dev/jjs/impl/gflow/constants/ConstantsAnalysisTransformationTest.java b/dev/core/test/com/google/gwt/dev/jjs/impl/gflow/constants/ConstantsAnalysisTransformationTest.java
index 840e7de..6b7af48 100644
--- a/dev/core/test/com/google/gwt/dev/jjs/impl/gflow/constants/ConstantsAnalysisTransformationTest.java
+++ b/dev/core/test/com/google/gwt/dev/jjs/impl/gflow/constants/ConstantsAnalysisTransformationTest.java
@@ -134,6 +134,21 @@
     transform("boolean", "String s = baz(); if (s == null) return false; return s != null;").into(
         "String s = EntryPoint.baz();", "if (s == null)", "  return false;", "return s != null;");
   }
+  
+  public void testImplicitCasts() throws Exception {
+    transform("long", 
+        "int bar = 0x12345678;",
+        "bar = bar * 1234;",
+        "long lng = bar;",
+        "long lng8 = lng << 8;",
+        "return lng8;"
+        ).into(
+            "  int bar = 305419896;", 
+            "  bar = -1068970384;",
+            "  long lng = -1068970384;", 
+            "  long lng8 = lng << 8;", 
+            "  return lng8;");
+  }
 
   @Override
   protected IntegratedAnalysis<CfgNode<?>, CfgEdge, CfgTransformer, Cfg, 
diff --git a/dev/core/test/com/google/gwt/dev/jjs/impl/gflow/copy/CopyAnalysisTransformationTest.java b/dev/core/test/com/google/gwt/dev/jjs/impl/gflow/copy/CopyAnalysisTransformationTest.java
index e9c3030..617ea5b 100644
--- a/dev/core/test/com/google/gwt/dev/jjs/impl/gflow/copy/CopyAnalysisTransformationTest.java
+++ b/dev/core/test/com/google/gwt/dev/jjs/impl/gflow/copy/CopyAnalysisTransformationTest.java
@@ -62,6 +62,21 @@
         "return i;");
   }
 
+  public void testImplicitConversion() throws Exception {
+    transform("long", 
+        "int bar = 0x12345678;",
+        "bar = bar * 1234;",
+        "long lng = bar;",
+        "long lng8 = lng << 8;",
+        "return lng8;"
+        ).into(
+            "  int bar = 305419896;", 
+            "  bar = bar * 1234;",
+            "  long lng = bar;", 
+            "  long lng8 = lng << 8;", 
+            "  return lng8;");
+  }
+
   @Override
   protected IntegratedAnalysis<CfgNode<?>, CfgEdge, CfgTransformer, Cfg, CopyAssumption> createIntegratedAnalysis() {
     return new CopyAnalysis();