The gflow constant analyzer assumes that parameters
could initially hold anything, rather than assuming
they haven't been initialized.  This caused problems
for code like:

foo(String param) {
if (something) {
param = null;
}
// at this point, analyzer thinks param==null
}

Review at http://gwt-code-reviews.appspot.com/405801


git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@7979 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/gflow/constants/ConstantsAnalysis.java b/dev/core/src/com/google/gwt/dev/jjs/impl/gflow/constants/ConstantsAnalysis.java
index c43aaac..09daf8b 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/gflow/constants/ConstantsAnalysis.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/gflow/constants/ConstantsAnalysis.java
@@ -15,8 +15,10 @@
  */
 package com.google.gwt.dev.jjs.impl.gflow.constants;
 
+import com.google.gwt.dev.jjs.ast.JParameterRef;
 import com.google.gwt.dev.jjs.impl.gflow.Analysis;
 import com.google.gwt.dev.jjs.impl.gflow.AssumptionMap;
+import com.google.gwt.dev.jjs.impl.gflow.AssumptionUtil;
 import com.google.gwt.dev.jjs.impl.gflow.IntegratedAnalysis;
 import com.google.gwt.dev.jjs.impl.gflow.cfg.Cfg;
 import com.google.gwt.dev.jjs.impl.gflow.cfg.CfgEdge;
@@ -44,6 +46,18 @@
 
   public void setInitialGraphAssumptions(Cfg graph,
       AssumptionMap<CfgEdge, ConstantsAssumption> assumptionMap) {
-    // bottom assumptions.
+    // Set all parameter assumptions to T
+
+    ConstantsAssumption.Updater updater = new ConstantsAssumption.Updater(null);
+    for (CfgNode<?> node : graph.getNodes()) {
+      Object jnode = node.getJNode();
+      if (jnode instanceof JParameterRef) {
+        updater.set(((JParameterRef) jnode).getParameter(), null);
+      }
+    }
+    ConstantsAssumption assumptions = updater.unwrap();
+
+    AssumptionUtil.setAssumptions(graph.getGraphInEdges(), assumptions,
+        assumptionMap);
   }
 }
diff --git a/dev/core/test/com/google/gwt/dev/jjs/impl/OptimizerTestBase.java b/dev/core/test/com/google/gwt/dev/jjs/impl/OptimizerTestBase.java
index 07ba206..d882ba6 100644
--- a/dev/core/test/com/google/gwt/dev/jjs/impl/OptimizerTestBase.java
+++ b/dev/core/test/com/google/gwt/dev/jjs/impl/OptimizerTestBase.java
@@ -188,6 +188,21 @@
    */
   protected JProgram compileSnippet(final String returnType,
       final String codeSnippet) throws UnableToCompleteException {
+    return compileSnippet(returnType, "", codeSnippet);
+  }
+
+  /**
+   * Returns the program that results from compiling the specified code snippet
+   * as the body of an entry point method.
+   * 
+   * @param returnType the return type of the method to compile; use "void" if
+   *          the code snippet has no return statement
+   * @param params the parameter list of the method to compile
+   * @param codeSnippet the body of the entry method
+   */
+  protected JProgram compileSnippet(final String returnType,
+      final String params, final String codeSnippet)
+      throws UnableToCompleteException {
     sourceOracle.addOrReplace(new MockJavaResource("test.EntryPoint") {
       @Override
       protected CharSequence getContent() {
@@ -200,7 +215,8 @@
         for (String snippetClassDecl : snippetClassDecls) {
           code.append(snippetClassDecl + ";\n");
         }
-        code.append("  public static " + returnType + " onModuleLoad() {\n");
+        code.append("  public static " + returnType + " onModuleLoad(" + params
+            + ") {\n");
         code.append(codeSnippet);
         code.append("  }\n");
         code.append("}\n");
diff --git a/dev/core/test/com/google/gwt/dev/jjs/impl/gflow/CfgAnalysisTestBase.java b/dev/core/test/com/google/gwt/dev/jjs/impl/gflow/CfgAnalysisTestBase.java
index 7fa25bf..9c56703 100644
--- a/dev/core/test/com/google/gwt/dev/jjs/impl/gflow/CfgAnalysisTestBase.java
+++ b/dev/core/test/com/google/gwt/dev/jjs/impl/gflow/CfgAnalysisTestBase.java
@@ -16,11 +16,16 @@
 public abstract class CfgAnalysisTestBase<A extends Assumption<A>> 
     extends OptimizerTestBase {
   protected boolean forward = true;
-  
+
   protected AnalysisResult analyze(String returnType, String... codeSnippet)
       throws UnableToCompleteException {
-    JProgram program = compileSnippet(returnType, Strings.join(codeSnippet,
-        "\n"));
+    return analyzeWithParams(returnType, "", codeSnippet);
+  }
+
+  protected AnalysisResult analyzeWithParams(String returnType, String params,
+      String... codeSnippet) throws UnableToCompleteException {
+    JProgram program = compileSnippet(returnType, params, Strings.join(
+        codeSnippet, "\n"));
     JMethodBody body = (JMethodBody) findMainMethod(program).getBody();
     Cfg cfgGraph = CfgBuilder.build(program, body.getBlock());
 
diff --git a/dev/core/test/com/google/gwt/dev/jjs/impl/gflow/constants/ConstantsAnalysisTest.java b/dev/core/test/com/google/gwt/dev/jjs/impl/gflow/constants/ConstantsAnalysisTest.java
index 4e371bc..82902bf 100644
--- a/dev/core/test/com/google/gwt/dev/jjs/impl/gflow/constants/ConstantsAnalysisTest.java
+++ b/dev/core/test/com/google/gwt/dev/jjs/impl/gflow/constants/ConstantsAnalysisTest.java
@@ -211,6 +211,27 @@
         );
   }
 
+  /**
+   * Parameters should have an initial assumption of non-constant.
+   */
+  public void testParamNonConstant() throws Exception {
+    analyzeWithParams("void", "int i, int j", "if (j == 0) { i = 0; } j=i; j=0;").into(
+        "BLOCK -> [* {i = T, j = T}]",
+        "STMT -> [* {i = T, j = T}]",
+        "READ(j) -> [* {i = T, j = T}]",
+        "COND (j == 0) -> [THEN=* {i = T, j = 0}, ELSE=1 {i = T, j = T}]",
+        "BLOCK -> [* {i = T, j = 0}]",
+        "STMT -> [* {i = T, j = 0}]",
+        "WRITE(i, 0) -> [* {i = 0, j = 0}]",
+        "1: STMT -> [* {i = T, j = T}]",
+        "READ(i) -> [* {i = T, j = T}]",
+        "WRITE(j, i) -> [* {i = T, j = T}]",
+        "STMT -> [* {i = T, j = T}]",
+        "WRITE(j, 0) -> [* {i = T, j = 0}]",
+        "END"
+      );
+  }
+
   @Override
   protected Analysis<CfgNode<?>, CfgEdge, Cfg, ConstantsAssumption> createAnalysis() {
     return new ConstantsAnalysis();