7040592: Gen.java: fix code for handling 'null' literal when expected type is array
authorsadayapalam
Mon, 23 Mar 2015 09:48:37 +0530
changeset 29777 95a89a2efd89
parent 29776 984a79b71cfe
child 29778 872a728c8075
7040592: Gen.java: fix code for handling 'null' literal when expected type is array Summary: Eliminate needless checkcast when null is assigned to a multi-dimensional array typedobject Reviewed-by: mcimadamore
langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Code.java
langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Gen.java
langtools/test/tools/javac/T7040592/CoerceNullToMoreSpecificTypeTest.java
langtools/test/tools/javac/T7040592/T7040592.java
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Code.java	Mon Mar 30 17:09:14 2015 +0530
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Code.java	Mon Mar 23 09:48:37 2015 +0530
@@ -497,13 +497,9 @@
         case aaload: {
             state.pop(1);// index
             Type a = state.stack[state.stacksize-1];
+            Assert.check(!a.hasTag(BOT)); // null type as is cannot be indexed.
             state.pop(1);
-            //sometimes 'null type' is treated as a one-dimensional array type
-            //see Gen.visitLiteral - we should handle this case accordingly
-            Type stackType = a.hasTag(BOT) ?
-                syms.objectType :
-                types.erasure(types.elemtype(a));
-            state.push(stackType); }
+            state.push(types.erasure(types.elemtype(a))); }
             break;
         case goto_:
             markDead();
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Gen.java	Mon Mar 30 17:09:14 2015 +0530
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Gen.java	Mon Mar 23 09:48:37 2015 +0530
@@ -1860,6 +1860,13 @@
     public void visitAssign(JCAssign tree) {
         Item l = genExpr(tree.lhs, tree.lhs.type);
         genExpr(tree.rhs, tree.lhs.type).load();
+        if (tree.rhs.type.hasTag(BOT)) {
+            /* This is just a case of widening reference conversion that per 5.1.5 simply calls
+               for "regarding a reference as having some other type in a manner that can be proved
+               correct at compile time."
+            */
+            code.state.forceStackTop(tree.lhs.type);
+        }
         result = items.makeAssignItem(l);
     }
 
@@ -2272,12 +2279,7 @@
     public void visitLiteral(JCLiteral tree) {
         if (tree.type.hasTag(BOT)) {
             code.emitop0(aconst_null);
-            if (types.dimensions(pt) > 1) {
-                code.emitop2(checkcast, makeRef(tree.pos(), pt));
-                result = items.makeStackItem(pt);
-            } else {
-                result = items.makeStackItem(tree.type);
-            }
+            result = items.makeStackItem(tree.type);
         }
         else
             result = items.makeImmediateItem(tree.type, tree.value);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/T7040592/CoerceNullToMoreSpecificTypeTest.java	Mon Mar 23 09:48:37 2015 +0530
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 7040592
+ * @summary Test that the assertion in State.forceStackTop does not fail at compile time.
+ */
+
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import org.w3c.dom.Element;
+
+public class CoerceNullToMoreSpecificTypeTest {
+    abstract class NodeImpl {
+    }
+
+    NodeImpl ownerNode;
+
+    public Element getElement() {
+        return (Element) (isOwned() ? ownerNode : null);
+    }
+
+    boolean isOwned() {
+        return true;
+    }
+
+    static void processArrays(boolean expectNulls, Object [] nulla, Object [][] nullaa) {
+        if (expectNulls) {
+            if (nulla != null || nullaa != null) {
+                throw new AssertionError("Null actual, but not null formal");
+            }
+        } else {
+            if (nulla.length != 123 || nullaa.length != 321)
+                throw new AssertionError("Wrong arrays received");
+        }
+    }
+
+    public static void main(String[] args) {
+        ArrayList<Class<?>> typeList = new ArrayList<>();
+        Field rf = null;
+        typeList.add((rf != null) ? rf.getType() : null);
+        processArrays(true, null, null);
+        processArrays(false, new Object[123], new Object[321][]);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/T7040592/T7040592.java	Mon Mar 23 09:48:37 2015 +0530
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 7040592
+ * @summary Verify that null can be assigned freely to array types without a checkcast
+ */
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.nio.file.Paths;
+
+public class T7040592 {
+
+    private static final String assertionErrorMsg =
+            "null should be assignable to array type without a checkcast";
+
+    public static void main(String[] args) {
+        new T7040592().run();
+    }
+
+    void run() {
+        check("-c", Paths.get(System.getProperty("test.classes"),
+                "T7040592_01.class").toString());
+    }
+
+    void check(String... params) {
+        StringWriter s;
+        String out;
+        try (PrintWriter pw = new PrintWriter(s = new StringWriter())) {
+            com.sun.tools.javap.Main.run(params, pw);
+            out = s.toString();
+        }
+        if (out.contains("checkcast")) {
+            throw new AssertionError(assertionErrorMsg);
+        }
+    }
+
+}
+
+class T7040592_01 {
+    static void handleArrays(Object [] a, Object [][] b, Object [][][] c) {
+    }
+    public static void main(String[] args) {
+        Object a[];
+        Object o = (a = null)[0];
+        Object b[][];
+        o = (b = null)[0][0];
+        Object c[][][];
+        o = (c = null)[0][0][0];
+        handleArrays(null, null, null);
+    }
+}