changeset 3269:6a8a8a94eaef

Fix: Compilation order dependencies causes classes to be erased before types are specialized Fix: calling a __RefOnly method from a nested class crashes javac
author mcimadamore
date Mon, 07 Dec 2015 16:50:51 +0000
parents 572d8ea3ca59
children 2b24dfe17c16
files src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java src/jdk.compiler/share/classes/com/sun/tools/javac/comp/SpecializeTypes.java src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TransTypes.java test/tools/javac/valhalla/typespec/Auxiliary06.java test/tools/javac/valhalla/typespec/TestRefOnly11.java
diffstat 5 files changed, 126 insertions(+), 34 deletions(-) [+]
line wrap: on
line diff
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java	Fri Dec 04 19:24:44 2015 +0000
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java	Mon Dec 07 16:50:51 2015 +0000
@@ -1692,7 +1692,7 @@
         }
 
         private boolean hasMatchingReceiver(Type site, Types types, WhereClause whereClauses) {
-            Type instSuper = types.asSuper(site, enclClass());
+            Type instSuper = types.asOuterSuper(site, enclClass());
             return (!instSuper.isParameterized() ||
                     instSuper.isRaw() ||
                     Tuple2.zip(instSuper.allparams(), instSuper.tsym.type.allparams()).stream()
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/SpecializeTypes.java	Fri Dec 04 19:24:44 2015 +0000
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/SpecializeTypes.java	Mon Dec 07 16:50:51 2015 +0000
@@ -42,6 +42,7 @@
 import com.sun.tools.javac.code.Types;
 import com.sun.tools.javac.code.Types.TypeVarContext;
 import com.sun.tools.javac.code.WhereClause;
+import com.sun.tools.javac.comp.CompileStates.CompileState;
 import com.sun.tools.javac.comp.Infer.InferredMethodType;
 import com.sun.tools.javac.jvm.Pool.MethodHandle;
 import com.sun.tools.javac.resources.CompilerProperties.Warnings;
@@ -117,6 +118,7 @@
 
     private Types types;
     private Enter enter;
+    private CompileStates compileStates;
     private Log log;
 
     private SpecializeTypes(Context context) {
@@ -124,6 +126,7 @@
         context.put(specializeTypesKey, this);
         types = Types.instance(context);
         enter = Enter.instance(context);
+        compileStates = CompileStates.instance(context);
         log = Log.instance(context);
     }
 
@@ -665,12 +668,48 @@
         });
     }
 
-    @Override
-    public void visitClassDef(JCClassDecl tree) {
+    private static final String statePreviousToFlowAssertMsg =
+            "The current compile state [%s] of class %s is previous to FLOW";
+
+    void translateClass(ClassSymbol c) {
+        for (Type st : types.directSupertypes(c.type)) {
+            // process supertype before derived
+            if (st.hasTag(CLASS)) {
+                translateClass((ClassSymbol) st.tsym);
+            }
+        }
+
+        Env<AttrContext> myEnv = enter.getEnv(c);
+        if (myEnv == null || (c.flags_field & Flags.TYPE_TRANSLATED) != 0) {
+            return;
+        }
+        c.flags_field |= Flags.TYPE_TRANSLATED;
+
+        /*  The two assertions below are set for early detection of any attempt
+         *  to translate a class that:
+         *
+         *  1) has no compile state being it the most outer class.
+         *     We accept this condition for inner classes.
+         *
+         *  2) has a compile state which is previous to Flow state.
+         */
+        boolean envHasCompState = compileStates.get(myEnv) != null;
+        if (!envHasCompState && c.outermostClass() == c) {
+            Assert.error("No info for outermost class: " + myEnv.enclClass.sym);
+        }
+
+        if (envHasCompState &&
+                CompileState.FLOW.isAfter(compileStates.get(myEnv))) {
+            Assert.error(String.format(statePreviousToFlowAssertMsg,
+                    compileStates.get(myEnv), myEnv.enclClass.sym));
+        }
+
         List<JCTree> prevPendingDefs = pendingDefs;
         Map<MethodSymbol, JCMethodDecl> prevSuperBridges = superBridges;
         ClassSymbol prevClass = currentClass;
+
         try {
+            JCClassDecl tree = (JCClassDecl)myEnv.tree;
             pendingDefs = List.nil();
             superBridges = new HashMap<>();
             currentClass = tree.sym;
@@ -705,6 +744,11 @@
         }
     }
 
+    public void visitClassDef(JCClassDecl tree) {
+        translateClass(tree.sym);
+        result = tree;
+    }
+
     @Override
     public void visitIndexed(JCArrayAccess tree) {
         tree.index = translate(tree.index);
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TransTypes.java	Fri Dec 04 19:24:44 2015 +0000
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TransTypes.java	Mon Dec 07 16:50:51 2015 +0000
@@ -964,38 +964,7 @@
             "The current compile state [%s] of class %s is previous to FLOW";
 
     void translateClass(ClassSymbol c) {
-        for (Type st : types.directSupertypes(c.type)) {
-            // process supertype before derived
-            if (st.hasTag(CLASS)) {
-                translateClass((ClassSymbol)st.tsym);
-            }
-        }
-
         Env<AttrContext> myEnv = enter.getEnv(c);
-        if (myEnv == null || (c.flags_field & TYPE_TRANSLATED) != 0) {
-            return;
-        }
-        c.flags_field |= TYPE_TRANSLATED;
-
-        /*  The two assertions below are set for early detection of any attempt
-         *  to translate a class that:
-         *
-         *  1) has no compile state being it the most outer class.
-         *     We accept this condition for inner classes.
-         *
-         *  2) has a compile state which is previous to Flow state.
-         */
-        boolean envHasCompState = compileStates.get(myEnv) != null;
-        if (!envHasCompState && c.outermostClass() == c) {
-            Assert.error("No info for outermost class: " + myEnv.enclClass.sym);
-        }
-
-        if (envHasCompState &&
-                CompileState.FLOW.isAfter(compileStates.get(myEnv))) {
-            Assert.error(String.format(statePreviousToFlowAssertMsg,
-                    compileStates.get(myEnv), myEnv.enclClass.sym));
-        }
-
         Env<AttrContext> oldEnv = env;
         try {
             env = myEnv;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/valhalla/typespec/Auxiliary06.java	Mon Dec 07 16:50:51 2015 +0000
@@ -0,0 +1,42 @@
+/*
+ * 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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
+ * @summary compilation order dependencies causes classes to be erased before types are specialized
+ * @compile Auxiliary06.java
+ */
+class Auxiliary06_01<any K, any V> {
+
+    static final class Entry<any K, any V> extends AuxiliaryClass06_02.Entry<K,V> { }
+
+    final int hash(boolean cond, K key, int h) {
+        return cond ? 0 : (h = key.hashCode()) ^ (h >>> 16);
+    }
+}
+
+class AuxiliaryClass06_02<any K, any V> extends Auxiliary06_01<K, V> {
+   static class Entry<any K, any V>  { }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/valhalla/typespec/TestRefOnly11.java	Mon Dec 07 16:50:51 2015 +0000
@@ -0,0 +1,37 @@
+/*
+ * 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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
+ * @summary calling a __RefOnly method from a nested class crashes javac
+ * @compile TestRefOnly11.java
+ */
+class TestRefOnly11<any K, any V> {
+    __WhereRef(K) __WhereRef(V) boolean containsKey(Object key) { return false; }
+
+    class Nested {
+        final public __WhereRef(K) __WhereRef(V) boolean contains(Object o) { return containsKey(o); }
+    }
+}