Mon, 11 Nov 2013 09:47:46 -0500
8027439: Compile-time error in the case of ((Integer[] & Serializable)new Integer[1]).getClass()
8027253: javac illegally accepts array as bound
Summary: backing out change allowing arrays in intersection types
Reviewed-by: vromero
1.1 --- a/src/share/classes/com/sun/tools/javac/code/Types.java Sat Nov 09 15:24:38 2013 +0100 1.2 +++ b/src/share/classes/com/sun/tools/javac/code/Types.java Mon Nov 11 09:47:46 2013 -0500 1.3 @@ -244,7 +244,7 @@ 1.4 public Type visitClassType(ClassType t, Symbol sym) { 1.5 if (t.tsym == sym) 1.6 return t; 1.7 - Type base = asSuper(sym.type, t); 1.8 + Type base = asSuper(sym.type, t.tsym); 1.9 if (base == null) 1.10 return null; 1.11 ListBuffer<Type> from = new ListBuffer<Type>(); 1.12 @@ -687,7 +687,7 @@ 1.13 (t.flags() & SYNTHETIC) == 0; 1.14 } 1.15 }; 1.16 - private boolean pendingBridges(ClassSymbol origin, TypeSymbol sym) { 1.17 + private boolean pendingBridges(ClassSymbol origin, TypeSymbol s) { 1.18 //a symbol will be completed from a classfile if (a) symbol has 1.19 //an associated file object with CLASS kind and (b) the symbol has 1.20 //not been entered 1.21 @@ -696,11 +696,11 @@ 1.22 enter.getEnv(origin) == null) { 1.23 return false; 1.24 } 1.25 - if (origin == sym) { 1.26 + if (origin == s) { 1.27 return true; 1.28 } 1.29 for (Type t : interfaces(origin.type)) { 1.30 - if (pendingBridges((ClassSymbol)t.tsym, sym)) { 1.31 + if (pendingBridges((ClassSymbol)t.tsym, s)) { 1.32 return true; 1.33 } 1.34 } 1.35 @@ -761,7 +761,7 @@ 1.36 } else if (t.hasTag(TYPEVAR)) { 1.37 return isSubtypeUnchecked(t.getUpperBound(), s, warn); 1.38 } else if (!s.isRaw()) { 1.39 - Type t2 = asSuper(t, s); 1.40 + Type t2 = asSuper(t, s.tsym); 1.41 if (t2 != null && t2.isRaw()) { 1.42 if (isReifiable(s)) { 1.43 warn.silentWarn(LintCategory.UNCHECKED); 1.44 @@ -914,7 +914,7 @@ 1.45 1.46 @Override 1.47 public Boolean visitClassType(ClassType t, Type s) { 1.48 - Type sup = asSuper(t, s); 1.49 + Type sup = asSuper(t, s.tsym); 1.50 return sup != null 1.51 && sup.tsym == s.tsym 1.52 // You're not allowed to write 1.53 @@ -1935,42 +1935,30 @@ 1.54 * @param t a type 1.55 * @param sym a symbol 1.56 */ 1.57 - public Type asSuper(Type t, Symbol s) { 1.58 - return asSuper(t, s.type); 1.59 - } 1.60 - 1.61 - public Type asSuper(Type t, Type s) { 1.62 - return asSuper.visit(t, s); 1.63 + public Type asSuper(Type t, Symbol sym) { 1.64 + return asSuper.visit(t, sym); 1.65 } 1.66 // where 1.67 - private SimpleVisitor<Type,Type> asSuper = new SimpleVisitor<Type,Type>() { 1.68 - 1.69 - public Type visitType(Type t, Type s) { 1.70 + private SimpleVisitor<Type,Symbol> asSuper = new SimpleVisitor<Type,Symbol>() { 1.71 + 1.72 + public Type visitType(Type t, Symbol sym) { 1.73 return null; 1.74 } 1.75 1.76 @Override 1.77 - public Type visitClassType(ClassType t, Type s) { 1.78 - if (t.tsym == s.tsym) 1.79 + public Type visitClassType(ClassType t, Symbol sym) { 1.80 + if (t.tsym == sym) 1.81 return t; 1.82 1.83 Type st = supertype(t); 1.84 - 1.85 - switch(st.getTag()) { 1.86 - default: break; 1.87 - case CLASS: 1.88 - case ARRAY: 1.89 - case TYPEVAR: 1.90 - case ERROR: { 1.91 - Type x = asSuper(st, s); 1.92 + if (st.hasTag(CLASS) || st.hasTag(TYPEVAR) || st.hasTag(ERROR)) { 1.93 + Type x = asSuper(st, sym); 1.94 if (x != null) 1.95 return x; 1.96 - } break; 1.97 } 1.98 - 1.99 - if ((s.tsym.flags() & INTERFACE) != 0) { 1.100 + if ((sym.flags() & INTERFACE) != 0) { 1.101 for (List<Type> l = interfaces(t); l.nonEmpty(); l = l.tail) { 1.102 - Type x = asSuper(l.head, s); 1.103 + Type x = asSuper(l.head, sym); 1.104 if (x != null) 1.105 return x; 1.106 } 1.107 @@ -1979,20 +1967,22 @@ 1.108 } 1.109 1.110 @Override 1.111 - public Type visitArrayType(ArrayType t, Type s) { 1.112 - return isSubtype(t, s) ? s : null; 1.113 + public Type visitArrayType(ArrayType t, Symbol sym) { 1.114 + return isSubtype(t, sym.type) ? sym.type : null; 1.115 } 1.116 1.117 @Override 1.118 - public Type visitTypeVar(TypeVar t, Type s) { 1.119 - if (t.tsym == s.tsym) 1.120 + public Type visitTypeVar(TypeVar t, Symbol sym) { 1.121 + if (t.tsym == sym) 1.122 return t; 1.123 else 1.124 - return asSuper(t.bound, s); 1.125 + return asSuper(t.bound, sym); 1.126 } 1.127 1.128 @Override 1.129 - public Type visitErrorType(ErrorType t, Type s) { return t; } 1.130 + public Type visitErrorType(ErrorType t, Symbol sym) { 1.131 + return t; 1.132 + } 1.133 }; 1.134 1.135 /** 1.136 @@ -3573,9 +3563,9 @@ 1.137 //step 3 - for each element G in MEC, compute lci(Inv(G)) 1.138 List<Type> candidates = List.nil(); 1.139 for (Type erasedSupertype : mec) { 1.140 - List<Type> lci = List.of(asSuper(ts.head, erasedSupertype)); 1.141 + List<Type> lci = List.of(asSuper(ts.head, erasedSupertype.tsym)); 1.142 for (Type t : ts) { 1.143 - lci = intersect(lci, List.of(asSuper(t, erasedSupertype))); 1.144 + lci = intersect(lci, List.of(asSuper(t, erasedSupertype.tsym))); 1.145 } 1.146 candidates = candidates.appendList(lci); 1.147 } 1.148 @@ -3995,7 +3985,7 @@ 1.149 // The arguments to the supers could be unified here to 1.150 // get a more accurate analysis 1.151 while (commonSupers.nonEmpty()) { 1.152 - Type t1 = asSuper(from, commonSupers.head); 1.153 + Type t1 = asSuper(from, commonSupers.head.tsym); 1.154 Type t2 = commonSupers.head; // same as asSuper(to, commonSupers.head.tsym); 1.155 if (disjointTypes(t1.getTypeArguments(), t2.getTypeArguments())) 1.156 return false; 1.157 @@ -4026,7 +4016,7 @@ 1.158 from = target; 1.159 } 1.160 Assert.check((from.tsym.flags() & FINAL) != 0); 1.161 - Type t1 = asSuper(from, to); 1.162 + Type t1 = asSuper(from, to.tsym); 1.163 if (t1 == null) return false; 1.164 Type t2 = to; 1.165 if (disjointTypes(t1.getTypeArguments(), t2.getTypeArguments()))
2.1 --- a/src/share/classes/com/sun/tools/javac/comp/Attr.java Sat Nov 09 15:24:38 2013 +0100 2.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Attr.java Mon Nov 11 09:47:46 2013 -0500 2.3 @@ -58,7 +58,6 @@ 2.4 import static com.sun.tools.javac.code.Kinds.ERRONEOUS; 2.5 import static com.sun.tools.javac.code.TypeTag.*; 2.6 import static com.sun.tools.javac.code.TypeTag.WILDCARD; 2.7 -import static com.sun.tools.javac.code.TypeTag.ARRAY; 2.8 import static com.sun.tools.javac.tree.JCTree.Tag.*; 2.9 2.10 /** This is the main context-dependent analysis phase in GJC. It 2.11 @@ -806,44 +805,33 @@ 2.12 Type t = tree.type != null ? 2.13 tree.type : 2.14 attribType(tree, env); 2.15 - return checkBase(t, tree, env, classExpected, interfaceExpected, false, checkExtensible); 2.16 + return checkBase(t, tree, env, classExpected, interfaceExpected, checkExtensible); 2.17 } 2.18 Type checkBase(Type t, 2.19 JCTree tree, 2.20 Env<AttrContext> env, 2.21 boolean classExpected, 2.22 - boolean interfacesOnlyExpected, 2.23 - boolean interfacesOrArraysExpected, 2.24 + boolean interfaceExpected, 2.25 boolean checkExtensible) { 2.26 if (t.isErroneous()) 2.27 return t; 2.28 - if (t.hasTag(TYPEVAR) && !classExpected && 2.29 - !interfacesOrArraysExpected && !interfacesOnlyExpected) { 2.30 + if (t.hasTag(TYPEVAR) && !classExpected && !interfaceExpected) { 2.31 // check that type variable is already visible 2.32 if (t.getUpperBound() == null) { 2.33 log.error(tree.pos(), "illegal.forward.ref"); 2.34 return types.createErrorType(t); 2.35 } 2.36 - } else if (classExpected) { 2.37 + } else { 2.38 t = chk.checkClassType(tree.pos(), t, checkExtensible|!allowGenerics); 2.39 - } else { 2.40 - t = chk.checkClassOrArrayType(tree.pos(), t, 2.41 - checkExtensible|!allowGenerics); 2.42 } 2.43 - if (interfacesOnlyExpected && !t.tsym.isInterface()) { 2.44 + if (interfaceExpected && (t.tsym.flags() & INTERFACE) == 0) { 2.45 log.error(tree.pos(), "intf.expected.here"); 2.46 // return errType is necessary since otherwise there might 2.47 // be undetected cycles which cause attribution to loop 2.48 return types.createErrorType(t); 2.49 - } else if (interfacesOrArraysExpected && 2.50 - !(t.tsym.isInterface() || t.getTag() == ARRAY)) { 2.51 - log.error(tree.pos(), "intf.or.array.expected.here"); 2.52 - // return errType is necessary since otherwise there might 2.53 - // be undetected cycles which cause attribution to loop 2.54 - return types.createErrorType(t); 2.55 } else if (checkExtensible && 2.56 classExpected && 2.57 - t.tsym.isInterface()) { 2.58 + (t.tsym.flags() & INTERFACE) != 0) { 2.59 log.error(tree.pos(), "no.intf.expected.here"); 2.60 return types.createErrorType(t); 2.61 } 2.62 @@ -855,12 +843,6 @@ 2.63 chk.checkNonCyclic(tree.pos(), t); 2.64 return t; 2.65 } 2.66 - //where 2.67 - private Object asTypeParam(Type t) { 2.68 - return (t.hasTag(TYPEVAR)) 2.69 - ? diags.fragment("type.parameter", t) 2.70 - : t; 2.71 - } 2.72 2.73 Type attribIdentAsEnumType(Env<AttrContext> env, JCIdent id) { 2.74 Assert.check((env.enclClass.sym.flags() & ENUM) != 0); 2.75 @@ -3985,7 +3967,7 @@ 2.76 Set<Type> boundSet = new HashSet<Type>(); 2.77 if (bounds.nonEmpty()) { 2.78 // accept class or interface or typevar as first bound. 2.79 - bounds.head.type = checkBase(bounds.head.type, bounds.head, env, false, false, false, false); 2.80 + bounds.head.type = checkBase(bounds.head.type, bounds.head, env, false, false, false); 2.81 boundSet.add(types.erasure(bounds.head.type)); 2.82 if (bounds.head.type.isErroneous()) { 2.83 return bounds.head.type; 2.84 @@ -4001,7 +3983,7 @@ 2.85 // if first bound was a class or interface, accept only interfaces 2.86 // as further bounds. 2.87 for (JCExpression bound : bounds.tail) { 2.88 - bound.type = checkBase(bound.type, bound, env, false, false, true, false); 2.89 + bound.type = checkBase(bound.type, bound, env, false, true, false); 2.90 if (bound.type.isErroneous()) { 2.91 bounds = List.of(bound); 2.92 }
3.1 --- a/src/share/classes/com/sun/tools/javac/comp/Check.java Sat Nov 09 15:24:38 2013 +0100 3.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Check.java Mon Nov 11 09:47:46 2013 -0500 3.3 @@ -707,37 +707,6 @@ 3.4 return t; 3.5 } 3.6 3.7 - // Analog of checkClassType that calls checkClassOrArrayType instead 3.8 - Type checkClassOrArrayType(DiagnosticPosition pos, 3.9 - Type t, boolean noBounds) { 3.10 - t = checkClassOrArrayType(pos, t); 3.11 - if (noBounds && t.isParameterized()) { 3.12 - List<Type> args = t.getTypeArguments(); 3.13 - while (args.nonEmpty()) { 3.14 - if (args.head.hasTag(WILDCARD)) 3.15 - return typeTagError(pos, 3.16 - diags.fragment("type.req.exact"), 3.17 - args.head); 3.18 - args = args.tail; 3.19 - } 3.20 - } 3.21 - return t; 3.22 - } 3.23 - 3.24 - /** Check that type is a reifiable class, interface or array type. 3.25 - * @param pos Position to be used for error reporting. 3.26 - * @param t The type to be checked. 3.27 - */ 3.28 - Type checkReifiableReferenceType(DiagnosticPosition pos, Type t) { 3.29 - t = checkClassOrArrayType(pos, t); 3.30 - if (!t.isErroneous() && !types.isReifiable(t)) { 3.31 - log.error(pos, "illegal.generic.type.for.instof"); 3.32 - return types.createErrorType(t); 3.33 - } else { 3.34 - return t; 3.35 - } 3.36 - } 3.37 - 3.38 /** Check that type is a reference type, i.e. a class, interface or array type 3.39 * or a type variable. 3.40 * @param pos Position to be used for error reporting. 3.41 @@ -2253,9 +2222,6 @@ 3.42 seen = seen.prepend(tv); 3.43 for (Type b : types.getBounds(tv)) 3.44 checkNonCyclic1(pos, b, seen); 3.45 - } else if (t.hasTag(ARRAY)) { 3.46 - final ArrayType at = (ArrayType)t.unannotatedType(); 3.47 - checkNonCyclic1(pos, at.elemtype, seen); 3.48 } 3.49 } 3.50
4.1 --- a/src/share/classes/com/sun/tools/javac/resources/compiler.properties Sat Nov 09 15:24:38 2013 +0100 4.2 +++ b/src/share/classes/com/sun/tools/javac/resources/compiler.properties Mon Nov 11 09:47:46 2013 -0500 4.3 @@ -575,9 +575,6 @@ 4.4 compiler.err.intf.expected.here=\ 4.5 interface expected here 4.6 4.7 -compiler.err.intf.or.array.expected.here=\ 4.8 - interface or array type expected here 4.9 - 4.10 compiler.err.intf.meth.cant.have.body=\ 4.11 interface abstract methods cannot have body 4.12
5.1 --- a/test/tools/javac/ArraysInIntersections.java Sat Nov 09 15:24:38 2013 +0100 5.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 5.3 @@ -1,39 +0,0 @@ 5.4 -/* 5.5 - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. 5.6 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5.7 - * 5.8 - * This code is free software; you can redistribute it and/or modify it 5.9 - * under the terms of the GNU General Public License version 2 only, as 5.10 - * published by the Free Software Foundation. 5.11 - * 5.12 - * This code is distributed in the hope that it will be useful, but WITHOUT 5.13 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 5.14 - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 5.15 - * version 2 for more details (a copy is included in the LICENSE file that 5.16 - * accompanied this code). 5.17 - * 5.18 - * You should have received a copy of the GNU General Public License version 5.19 - * 2 along with this work; if not, write to the Free Software Foundation, 5.20 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 5.21 - * 5.22 - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 5.23 - * or visit www.oracle.com if you need additional information or have any 5.24 - * questions. 5.25 - */ 5.26 - 5.27 -/* 5.28 - * @test 5.29 - * @bug 8021339 5.30 - * @summary Allow arrays in intersection types 5.31 - * @compile ArraysInIntersections.java 5.32 - */ 5.33 - 5.34 -import java.io.Serializable; 5.35 - 5.36 -public class ArraysInIntersections<T extends Serializable & Integer[]> { 5.37 - 5.38 - public <S extends Serializable & Integer[]> Object m() { 5.39 - return (Serializable & Integer[]) new Integer[1]; 5.40 - } 5.41 - 5.42 -}
6.1 --- a/test/tools/javac/InferArraysInIntersections.java Sat Nov 09 15:24:38 2013 +0100 6.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 6.3 @@ -1,38 +0,0 @@ 6.4 -/* 6.5 - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. 6.6 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 6.7 - * 6.8 - * This code is free software; you can redistribute it and/or modify it 6.9 - * under the terms of the GNU General Public License version 2 only, as 6.10 - * published by the Free Software Foundation. 6.11 - * 6.12 - * This code is distributed in the hope that it will be useful, but WITHOUT 6.13 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 6.14 - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 6.15 - * version 2 for more details (a copy is included in the LICENSE file that 6.16 - * accompanied this code). 6.17 - * 6.18 - * You should have received a copy of the GNU General Public License version 6.19 - * 2 along with this work; if not, write to the Free Software Foundation, 6.20 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 6.21 - * 6.22 - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 6.23 - * or visit www.oracle.com if you need additional information or have any 6.24 - * questions. 6.25 - */ 6.26 - 6.27 -/* 6.28 - * @test 6.29 - * @bug 8021339 6.30 - * @summary Allow arrays in intersection types 6.31 - * @compile -doe -XDrawDiagnostics InferArraysInIntersections.java 6.32 - */ 6.33 -import java.util.*; 6.34 - 6.35 -class InferArraysInIntersections { 6.36 - <T> T m(List<? super T> t) { return null; } 6.37 - 6.38 - void test(List<char[]> lc) { 6.39 - Runnable r = m(lc); //inference fails here 6.40 - } 6.41 -}
7.1 --- a/test/tools/javac/diags/examples/InterfaceOrArrayExpected.java Sat Nov 09 15:24:38 2013 +0100 7.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 7.3 @@ -1,28 +0,0 @@ 7.4 -/* 7.5 - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. 7.6 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 7.7 - * 7.8 - * This code is free software; you can redistribute it and/or modify it 7.9 - * under the terms of the GNU General Public License version 2 only, as 7.10 - * published by the Free Software Foundation. 7.11 - * 7.12 - * This code is distributed in the hope that it will be useful, but WITHOUT 7.13 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 7.14 - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 7.15 - * version 2 for more details (a copy is included in the LICENSE file that 7.16 - * accompanied this code). 7.17 - * 7.18 - * You should have received a copy of the GNU General Public License version 7.19 - * 2 along with this work; if not, write to the Free Software Foundation, 7.20 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 7.21 - * 7.22 - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 7.23 - * or visit www.oracle.com if you need additional information or have any 7.24 - * questions. 7.25 - */ 7.26 - 7.27 -// key: compiler.err.intf.or.array.expected.here 7.28 - 7.29 -import java.util.List; 7.30 - 7.31 -class InterfaceExpected<T extends List & String> { }
8.1 --- a/test/tools/javac/generics/typevars/6680106/T6680106.out Sat Nov 09 15:24:38 2013 +0100 8.2 +++ b/test/tools/javac/generics/typevars/6680106/T6680106.out Mon Nov 11 09:47:46 2013 -0500 8.3 @@ -1,7 +1,13 @@ 8.4 -T6680106.java:11:14: compiler.err.cyclic.inheritance: T 8.5 -T6680106.java:12:14: compiler.err.cyclic.inheritance: T 8.6 -T6680106.java:13:14: compiler.err.cyclic.inheritance: T 8.7 -T6680106.java:14:14: compiler.err.cyclic.inheritance: T 8.8 -T6680106.java:15:14: compiler.err.cyclic.inheritance: T 8.9 -T6680106.java:16:14: compiler.err.cyclic.inheritance: T 8.10 -6 errors 8.11 +T6680106.java:11:25: compiler.err.type.found.req: T[], (compiler.misc.type.req.class) 8.12 +T6680106.java:12:25: compiler.err.type.found.req: S[], (compiler.misc.type.req.class) 8.13 +T6680106.java:12:40: compiler.err.type.found.req: T[], (compiler.misc.type.req.class) 8.14 +T6680106.java:13:25: compiler.err.type.found.req: S[], (compiler.misc.type.req.class) 8.15 +T6680106.java:13:40: compiler.err.type.found.req: U[], (compiler.misc.type.req.class) 8.16 +T6680106.java:13:55: compiler.err.type.found.req: T[], (compiler.misc.type.req.class) 8.17 +T6680106.java:14:30: compiler.err.type.found.req: T[], (compiler.misc.type.req.class) 8.18 +T6680106.java:15:30: compiler.err.type.found.req: S[], (compiler.misc.type.req.class) 8.19 +T6680106.java:15:50: compiler.err.type.found.req: T[], (compiler.misc.type.req.class) 8.20 +T6680106.java:16:30: compiler.err.type.found.req: S[], (compiler.misc.type.req.class) 8.21 +T6680106.java:16:50: compiler.err.type.found.req: U[], (compiler.misc.type.req.class) 8.22 +T6680106.java:16:70: compiler.err.type.found.req: T[], (compiler.misc.type.req.class) 8.23 +12 errors