Tue, 28 Oct 2014 14:59:42 +0000
8058511: StackOverflowError at com.sun.tools.javac.code.Types.lub
Summary: Lub crashes when handling typevar with array bound
Reviewed-by: vromero, dlsmith
1.1 --- a/src/share/classes/com/sun/tools/javac/code/Types.java Tue Oct 28 08:56:23 2014 +0100 1.2 +++ b/src/share/classes/com/sun/tools/javac/code/Types.java Tue Oct 28 14:59:42 2014 +0000 1.3 @@ -1892,7 +1892,12 @@ 1.4 * Mapping to take element type of an arraytype 1.5 */ 1.6 private Mapping elemTypeFun = new Mapping ("elemTypeFun") { 1.7 - public Type apply(Type t) { return elemtype(t); } 1.8 + public Type apply(Type t) { 1.9 + while (t.hasTag(TYPEVAR)) { 1.10 + t = t.getUpperBound(); 1.11 + } 1.12 + return elemtype(t); 1.13 + } 1.14 }; 1.15 1.16 /** 1.17 @@ -3521,40 +3526,46 @@ 1.18 } 1.19 1.20 /** 1.21 - * Return the least upper bound of pair of types. if the lub does 1.22 + * Return the least upper bound of list of types. if the lub does 1.23 * not exist return null. 1.24 */ 1.25 - public Type lub(Type t1, Type t2) { 1.26 - return lub(List.of(t1, t2)); 1.27 + public Type lub(List<Type> ts) { 1.28 + return lub(ts.toArray(new Type[ts.length()])); 1.29 } 1.30 1.31 /** 1.32 * Return the least upper bound (lub) of set of types. If the lub 1.33 * does not exist return the type of null (bottom). 1.34 */ 1.35 - public Type lub(List<Type> ts) { 1.36 + public Type lub(Type... ts) { 1.37 + final int UNKNOWN_BOUND = 0; 1.38 final int ARRAY_BOUND = 1; 1.39 final int CLASS_BOUND = 2; 1.40 - int boundkind = 0; 1.41 - for (Type t : ts) { 1.42 + 1.43 + int[] kinds = new int[ts.length]; 1.44 + 1.45 + int boundkind = UNKNOWN_BOUND; 1.46 + for (int i = 0 ; i < ts.length ; i++) { 1.47 + Type t = ts[i]; 1.48 switch (t.getTag()) { 1.49 case CLASS: 1.50 - boundkind |= CLASS_BOUND; 1.51 + boundkind |= kinds[i] = CLASS_BOUND; 1.52 break; 1.53 case ARRAY: 1.54 - boundkind |= ARRAY_BOUND; 1.55 + boundkind |= kinds[i] = ARRAY_BOUND; 1.56 break; 1.57 case TYPEVAR: 1.58 do { 1.59 t = t.getUpperBound(); 1.60 } while (t.hasTag(TYPEVAR)); 1.61 if (t.hasTag(ARRAY)) { 1.62 - boundkind |= ARRAY_BOUND; 1.63 + boundkind |= kinds[i] = ARRAY_BOUND; 1.64 } else { 1.65 - boundkind |= CLASS_BOUND; 1.66 + boundkind |= kinds[i] = CLASS_BOUND; 1.67 } 1.68 break; 1.69 default: 1.70 + kinds[i] = UNKNOWN_BOUND; 1.71 if (t.isPrimitive()) 1.72 return syms.errType; 1.73 } 1.74 @@ -3565,15 +3576,16 @@ 1.75 1.76 case ARRAY_BOUND: 1.77 // calculate lub(A[], B[]) 1.78 - List<Type> elements = Type.map(ts, elemTypeFun); 1.79 - for (Type t : elements) { 1.80 - if (t.isPrimitive()) { 1.81 + Type[] elements = new Type[ts.length]; 1.82 + for (int i = 0 ; i < ts.length ; i++) { 1.83 + Type elem = elements[i] = elemTypeFun.apply(ts[i]); 1.84 + if (elem.isPrimitive()) { 1.85 // if a primitive type is found, then return 1.86 // arraySuperType unless all the types are the 1.87 // same 1.88 - Type first = ts.head; 1.89 - for (Type s : ts.tail) { 1.90 - if (!isSameType(first, s)) { 1.91 + Type first = ts[0]; 1.92 + for (int j = 1 ; j < ts.length ; j++) { 1.93 + if (!isSameType(first, ts[j])) { 1.94 // lub(int[], B[]) is Cloneable & Serializable 1.95 return arraySuperType(); 1.96 } 1.97 @@ -3588,13 +3600,20 @@ 1.98 1.99 case CLASS_BOUND: 1.100 // calculate lub(A, B) 1.101 - while (!ts.head.hasTag(CLASS) && !ts.head.hasTag(TYPEVAR)) { 1.102 - ts = ts.tail; 1.103 + int startIdx = 0; 1.104 + for (int i = 0; i < ts.length ; i++) { 1.105 + Type t = ts[i]; 1.106 + if (t.hasTag(CLASS) || t.hasTag(TYPEVAR)) { 1.107 + break; 1.108 + } else { 1.109 + startIdx++; 1.110 + } 1.111 } 1.112 - Assert.check(!ts.isEmpty()); 1.113 + Assert.check(startIdx < ts.length); 1.114 //step 1 - compute erased candidate set (EC) 1.115 - List<Type> cl = erasedSupertypes(ts.head); 1.116 - for (Type t : ts.tail) { 1.117 + List<Type> cl = erasedSupertypes(ts[startIdx]); 1.118 + for (int i = startIdx + 1 ; i < ts.length ; i++) { 1.119 + Type t = ts[i]; 1.120 if (t.hasTag(CLASS) || t.hasTag(TYPEVAR)) 1.121 cl = intersect(cl, erasedSupertypes(t)); 1.122 } 1.123 @@ -3603,9 +3622,9 @@ 1.124 //step 3 - for each element G in MEC, compute lci(Inv(G)) 1.125 List<Type> candidates = List.nil(); 1.126 for (Type erasedSupertype : mec) { 1.127 - List<Type> lci = List.of(asSuper(ts.head, erasedSupertype.tsym)); 1.128 - for (Type t : ts) { 1.129 - lci = intersect(lci, List.of(asSuper(t, erasedSupertype.tsym))); 1.130 + List<Type> lci = List.of(asSuper(ts[startIdx], erasedSupertype.tsym)); 1.131 + for (int i = startIdx + 1 ; i < ts.length ; i++) { 1.132 + lci = intersect(lci, List.of(asSuper(ts[i], erasedSupertype.tsym))); 1.133 } 1.134 candidates = candidates.appendList(lci); 1.135 } 1.136 @@ -3616,9 +3635,9 @@ 1.137 default: 1.138 // calculate lub(A, B[]) 1.139 List<Type> classes = List.of(arraySuperType()); 1.140 - for (Type t : ts) { 1.141 - if (!t.hasTag(ARRAY)) // Filter out any arrays 1.142 - classes = classes.prepend(t); 1.143 + for (int i = 0 ; i < ts.length ; i++) { 1.144 + if (kinds[i] != ARRAY_BOUND) // Filter out any arrays 1.145 + classes = classes.prepend(ts[i]); 1.146 } 1.147 // lub(A, B[]) is lub(A, arraySuperType) 1.148 return lub(classes);
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/test/tools/javac/generics/inference/8058511/T8058511a.java Tue Oct 28 14:59:42 2014 +0000 2.3 @@ -0,0 +1,38 @@ 2.4 +/* 2.5 + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. 2.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 2.7 + * 2.8 + * This code is free software; you can redistribute it and/or modify it 2.9 + * under the terms of the GNU General Public License version 2 only, as 2.10 + * published by the Free Software Foundation. Oracle designates this 2.11 + * particular file as subject to the "Classpath" exception as provided 2.12 + * by Oracle in the LICENSE file that accompanied this code. 2.13 + * 2.14 + * This code is distributed in the hope that it will be useful, but WITHOUT 2.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 2.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 2.17 + * version 2 for more details (a copy is included in the LICENSE file that 2.18 + * accompanied this code). 2.19 + * 2.20 + * You should have received a copy of the GNU General Public License version 2.21 + * 2 along with this work; if not, write to the Free Software Foundation, 2.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2.23 + * 2.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2.25 + * or visit www.oracle.com if you need additional information or have any 2.26 + * questions. 2.27 + */ 2.28 + 2.29 +/** 2.30 + * @test 2.31 + * @bug 8058511 2.32 + * @summary StackOverflowError at com.sun.tools.javac.code.Types.lub 2.33 + * @compile T8058511a.java 2.34 + */ 2.35 +class T8058511a { 2.36 + <Z> void choose(Z z1, Z z2) { } 2.37 + 2.38 + void test(Class<Double> cd, Class<? extends double[]> cdarr) { 2.39 + choose(cd, cdarr); 2.40 + } 2.41 +}
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 3.2 +++ b/test/tools/javac/generics/inference/8058511/T8058511b.java Tue Oct 28 14:59:42 2014 +0000 3.3 @@ -0,0 +1,36 @@ 3.4 +/* 3.5 + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. 3.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3.7 + * 3.8 + * This code is free software; you can redistribute it and/or modify it 3.9 + * under the terms of the GNU General Public License version 2 only, as 3.10 + * published by the Free Software Foundation. Oracle designates this 3.11 + * particular file as subject to the "Classpath" exception as provided 3.12 + * by Oracle in the LICENSE file that accompanied this code. 3.13 + * 3.14 + * This code is distributed in the hope that it will be useful, but WITHOUT 3.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 3.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 3.17 + * version 2 for more details (a copy is included in the LICENSE file that 3.18 + * accompanied this code). 3.19 + * 3.20 + * You should have received a copy of the GNU General Public License version 3.21 + * 2 along with this work; if not, write to the Free Software Foundation, 3.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 3.23 + * 3.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 3.25 + * or visit www.oracle.com if you need additional information or have any 3.26 + * questions. 3.27 + */ 3.28 + 3.29 +/** 3.30 + * @test 3.31 + * @bug 8058511 3.32 + * @summary StackOverflowError at com.sun.tools.javac.code.Types.lub 3.33 + * @compile T8058511b.java 3.34 + */ 3.35 +class T8058511b { 3.36 + void test(Class<Double> cd, Class<? extends double[]> cdarr) { 3.37 + ((false) ? cd : cdarr).toString(); 3.38 + } 3.39 +}
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 4.2 +++ b/test/tools/javac/generics/inference/8058511/T8058511c.java Tue Oct 28 14:59:42 2014 +0000 4.3 @@ -0,0 +1,38 @@ 4.4 +/* 4.5 + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. 4.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4.7 + * 4.8 + * This code is free software; you can redistribute it and/or modify it 4.9 + * under the terms of the GNU General Public License version 2 only, as 4.10 + * published by the Free Software Foundation. Oracle designates this 4.11 + * particular file as subject to the "Classpath" exception as provided 4.12 + * by Oracle in the LICENSE file that accompanied this code. 4.13 + * 4.14 + * This code is distributed in the hope that it will be useful, but WITHOUT 4.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 4.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 4.17 + * version 2 for more details (a copy is included in the LICENSE file that 4.18 + * accompanied this code). 4.19 + * 4.20 + * You should have received a copy of the GNU General Public License version 4.21 + * 2 along with this work; if not, write to the Free Software Foundation, 4.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 4.23 + * 4.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 4.25 + * or visit www.oracle.com if you need additional information or have any 4.26 + * questions. 4.27 + */ 4.28 + 4.29 +/** 4.30 + * @test 4.31 + * @bug 8058511 4.32 + * @summary StackOverflowError at com.sun.tools.javac.code.Types.lub 4.33 + * @compile T8058511c.java 4.34 + */ 4.35 +import java.util.List; 4.36 + 4.37 +class T8058511c { 4.38 + void test(List<? extends double[]> l) { 4.39 + (true ? l.get(0) : l.get(0)).toString(); 4.40 + } 4.41 +}