mirror of
https://github.com/openjdk/jdk.git
synced 2026-02-21 07:45:11 +00:00
8058511: StackOverflowError at com.sun.tools.javac.code.Types.lub
Lub crashes when handling typevar with array bound Reviewed-by: vromero, dlsmith
This commit is contained in:
parent
8f96799dd5
commit
2756ed20d7
@ -1889,7 +1889,12 @@ public class Types {
|
||||
* Mapping to take element type of an arraytype
|
||||
*/
|
||||
private Mapping elemTypeFun = new Mapping ("elemTypeFun") {
|
||||
public Type apply(Type t) { return elemtype(t); }
|
||||
public Type apply(Type t) {
|
||||
while (t.hasTag(TYPEVAR)) {
|
||||
t = t.getUpperBound();
|
||||
}
|
||||
return elemtype(t);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
@ -3531,40 +3536,46 @@ public class Types {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the least upper bound of pair of types. if the lub does
|
||||
* Return the least upper bound of list of types. if the lub does
|
||||
* not exist return null.
|
||||
*/
|
||||
public Type lub(Type t1, Type t2) {
|
||||
return lub(List.of(t1, t2));
|
||||
public Type lub(List<Type> ts) {
|
||||
return lub(ts.toArray(new Type[ts.length()]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the least upper bound (lub) of set of types. If the lub
|
||||
* does not exist return the type of null (bottom).
|
||||
*/
|
||||
public Type lub(List<Type> ts) {
|
||||
public Type lub(Type... ts) {
|
||||
final int UNKNOWN_BOUND = 0;
|
||||
final int ARRAY_BOUND = 1;
|
||||
final int CLASS_BOUND = 2;
|
||||
int boundkind = 0;
|
||||
for (Type t : ts) {
|
||||
|
||||
int[] kinds = new int[ts.length];
|
||||
|
||||
int boundkind = UNKNOWN_BOUND;
|
||||
for (int i = 0 ; i < ts.length ; i++) {
|
||||
Type t = ts[i];
|
||||
switch (t.getTag()) {
|
||||
case CLASS:
|
||||
boundkind |= CLASS_BOUND;
|
||||
boundkind |= kinds[i] = CLASS_BOUND;
|
||||
break;
|
||||
case ARRAY:
|
||||
boundkind |= ARRAY_BOUND;
|
||||
boundkind |= kinds[i] = ARRAY_BOUND;
|
||||
break;
|
||||
case TYPEVAR:
|
||||
do {
|
||||
t = t.getUpperBound();
|
||||
} while (t.hasTag(TYPEVAR));
|
||||
if (t.hasTag(ARRAY)) {
|
||||
boundkind |= ARRAY_BOUND;
|
||||
boundkind |= kinds[i] = ARRAY_BOUND;
|
||||
} else {
|
||||
boundkind |= CLASS_BOUND;
|
||||
boundkind |= kinds[i] = CLASS_BOUND;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
kinds[i] = UNKNOWN_BOUND;
|
||||
if (t.isPrimitive())
|
||||
return syms.errType;
|
||||
}
|
||||
@ -3575,15 +3586,16 @@ public class Types {
|
||||
|
||||
case ARRAY_BOUND:
|
||||
// calculate lub(A[], B[])
|
||||
List<Type> elements = Type.map(ts, elemTypeFun);
|
||||
for (Type t : elements) {
|
||||
if (t.isPrimitive()) {
|
||||
Type[] elements = new Type[ts.length];
|
||||
for (int i = 0 ; i < ts.length ; i++) {
|
||||
Type elem = elements[i] = elemTypeFun.apply(ts[i]);
|
||||
if (elem.isPrimitive()) {
|
||||
// if a primitive type is found, then return
|
||||
// arraySuperType unless all the types are the
|
||||
// same
|
||||
Type first = ts.head;
|
||||
for (Type s : ts.tail) {
|
||||
if (!isSameType(first, s)) {
|
||||
Type first = ts[0];
|
||||
for (int j = 1 ; j < ts.length ; j++) {
|
||||
if (!isSameType(first, ts[j])) {
|
||||
// lub(int[], B[]) is Cloneable & Serializable
|
||||
return arraySuperType();
|
||||
}
|
||||
@ -3598,13 +3610,20 @@ public class Types {
|
||||
|
||||
case CLASS_BOUND:
|
||||
// calculate lub(A, B)
|
||||
while (!ts.head.hasTag(CLASS) && !ts.head.hasTag(TYPEVAR)) {
|
||||
ts = ts.tail;
|
||||
int startIdx = 0;
|
||||
for (int i = 0; i < ts.length ; i++) {
|
||||
Type t = ts[i];
|
||||
if (t.hasTag(CLASS) || t.hasTag(TYPEVAR)) {
|
||||
break;
|
||||
} else {
|
||||
startIdx++;
|
||||
}
|
||||
}
|
||||
Assert.check(!ts.isEmpty());
|
||||
Assert.check(startIdx < ts.length);
|
||||
//step 1 - compute erased candidate set (EC)
|
||||
List<Type> cl = erasedSupertypes(ts.head);
|
||||
for (Type t : ts.tail) {
|
||||
List<Type> cl = erasedSupertypes(ts[startIdx]);
|
||||
for (int i = startIdx + 1 ; i < ts.length ; i++) {
|
||||
Type t = ts[i];
|
||||
if (t.hasTag(CLASS) || t.hasTag(TYPEVAR))
|
||||
cl = intersect(cl, erasedSupertypes(t));
|
||||
}
|
||||
@ -3613,9 +3632,9 @@ public class Types {
|
||||
//step 3 - for each element G in MEC, compute lci(Inv(G))
|
||||
List<Type> candidates = List.nil();
|
||||
for (Type erasedSupertype : mec) {
|
||||
List<Type> lci = List.of(asSuper(ts.head, erasedSupertype.tsym));
|
||||
for (Type t : ts) {
|
||||
lci = intersect(lci, List.of(asSuper(t, erasedSupertype.tsym)));
|
||||
List<Type> lci = List.of(asSuper(ts[startIdx], erasedSupertype.tsym));
|
||||
for (int i = startIdx + 1 ; i < ts.length ; i++) {
|
||||
lci = intersect(lci, List.of(asSuper(ts[i], erasedSupertype.tsym)));
|
||||
}
|
||||
candidates = candidates.appendList(lci);
|
||||
}
|
||||
@ -3626,9 +3645,9 @@ public class Types {
|
||||
default:
|
||||
// calculate lub(A, B[])
|
||||
List<Type> classes = List.of(arraySuperType());
|
||||
for (Type t : ts) {
|
||||
if (!t.hasTag(ARRAY)) // Filter out any arrays
|
||||
classes = classes.prepend(t);
|
||||
for (int i = 0 ; i < ts.length ; i++) {
|
||||
if (kinds[i] != ARRAY_BOUND) // Filter out any arrays
|
||||
classes = classes.prepend(ts[i]);
|
||||
}
|
||||
// lub(A, B[]) is lub(A, arraySuperType)
|
||||
return lub(classes);
|
||||
|
||||
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 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
|
||||
* @bug 8058511
|
||||
* @summary StackOverflowError at com.sun.tools.javac.code.Types.lub
|
||||
* @compile T8058511a.java
|
||||
*/
|
||||
class T8058511a {
|
||||
<Z> void choose(Z z1, Z z2) { }
|
||||
|
||||
void test(Class<Double> cd, Class<? extends double[]> cdarr) {
|
||||
choose(cd, cdarr);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 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
|
||||
* @bug 8058511
|
||||
* @summary StackOverflowError at com.sun.tools.javac.code.Types.lub
|
||||
* @compile T8058511b.java
|
||||
*/
|
||||
class T8058511b {
|
||||
void test(Class<Double> cd, Class<? extends double[]> cdarr) {
|
||||
((false) ? cd : cdarr).toString();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 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
|
||||
* @bug 8058511
|
||||
* @summary StackOverflowError at com.sun.tools.javac.code.Types.lub
|
||||
* @compile T8058511c.java
|
||||
*/
|
||||
import java.util.List;
|
||||
|
||||
class T8058511c {
|
||||
void test(List<? extends double[]> l) {
|
||||
(true ? l.get(0) : l.get(0)).toString();
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user