Details
-
Bug
-
Resolution: Unresolved
-
P3
-
None
-
8, 24
Description
The following example causes javac to crash with a StackOverflowError in Types.containsTypeRecursive.
Increasing javac's stack size doesn't help. I'm not sure if it's a true infinite loop or the amount of recursion required to terminate is prohibitively high.
The same crash reproduces at least as far back as JDK 8. (I didn't try earlier versions, and reproducing on 8 requires substituting an equivalent definition for List.of)
```
import java.util.List;
class T {
List<M<?, ?>> xs = List.of(new M<>(One.class), new M<>(Two.class), new M<>(Two.class));
}
class M<R extends Eight, I extends Nine<? extends R>> {
M(Class<? extends I> c) {}
}
class One implements Three<Five>, Six<One> {}
class Two implements Four<Seven>, Six<Two> {}
interface Three<R extends Eight> extends Nine<R> {}
interface Four<R extends Eight> extends Nine<R> {}
class Five extends Ten<Five> implements Eleven<Twelve>, Thirteen {}
interface Six<FullKeyT extends TwentyTwo> extends TwentyTwo {}
class Seven extends Ten<Seven> implements Eleven<Fourteen>, Thirteen {}
interface Eight {}
interface Nine<R extends Eight> extends TwentyTwo {}
class Ten<K extends TwentyTwo> implements TwentyTwo {}
interface Eleven<PkT extends Twenty> extends Twenty {}
class Twelve extends Ten<Twelve> implements Eleven<Sixteen>, Thirteen {}
interface Thirteen extends Seventeen {}
class Fourteen extends Ten<Fourteen> implements Eleven<Fifteen>, Thirteen {}
class Fifteen extends Ten<Fifteen> implements Eleven<Twelve>, Thirteen {}
class Sixteen extends Nineteen<Sixteen> implements Eighteen, Thirteen {}
interface Seventeen extends Twenty {}
interface Eighteen extends Twenty {}
class Nineteen<K extends Twenty> extends Ten<K> implements Twenty {}
interface Twenty extends TwentyTwo {}
class TwentyOne<R extends Eight> {}
interface TwentyTwo extends Eight {}
```
$ javac -fullversion T.java |& head -n 30
javac full version "24-ea+7-732"
The system is out of resources.
Consult the following stack trace for details.
java.lang.StackOverflowError
at jdk.compiler/com.sun.tools.javac.code.Types$HashCodeVisitor.visitType(Types.java:4192)
at jdk.compiler/com.sun.tools.javac.code.Types$HashCodeVisitor.visitType(Types.java:4190)
at jdk.compiler/com.sun.tools.javac.code.Type.accept(Type.java:223)
at jdk.compiler/com.sun.tools.javac.code.Types$UnaryVisitor.visit(Types.java:5000)
at jdk.compiler/com.sun.tools.javac.code.Types$HashCodeVisitor.visitClassType(Types.java:4197)
at jdk.compiler/com.sun.tools.javac.code.Types$HashCodeVisitor.visitClassType(Types.java:4190)
at jdk.compiler/com.sun.tools.javac.code.Type$ClassType.accept(Type.java:1053)
at jdk.compiler/com.sun.tools.javac.code.Types$UnaryVisitor.visit(Types.java:5000)
at jdk.compiler/com.sun.tools.javac.code.Types.hashCode(Types.java:4179)
at jdk.compiler/com.sun.tools.javac.code.Types.hashCode(Types.java:4173)
at jdk.compiler/com.sun.tools.javac.code.Types$TypePair.hashCode(Types.java:3855)
at java.base/java.util.HashMap.hash(HashMap.java:338)
at java.base/java.util.HashMap.put(HashMap.java:619)
at java.base/java.util.HashSet.add(HashSet.java:230)
at jdk.compiler/com.sun.tools.javac.code.Types$4.containsTypeRecursive(Types.java:1138)
at jdk.compiler/com.sun.tools.javac.code.Types$4.visitClassType(Types.java:1192)
at jdk.compiler/com.sun.tools.javac.code.Types$4.visitClassType(Types.java:1107)
at jdk.compiler/com.sun.tools.javac.code.Type$ClassType.accept(Type.java:1053)
at jdk.compiler/com.sun.tools.javac.code.Types$DefaultTypeVisitor.visit(Types.java:4920)
at jdk.compiler/com.sun.tools.javac.code.Types.isSubtype(Types.java:1103)
at jdk.compiler/com.sun.tools.javac.code.Types.isSubtype(Types.java:1087)
at jdk.compiler/com.sun.tools.javac.code.Types.isSubtypeNoCapture(Types.java:1077)
at jdk.compiler/com.sun.tools.javac.code.Types$6.visitWildcardType(Types.java:1588)
at jdk.compiler/com.sun.tools.javac.code.Types$6.visitWildcardType(Types.java:1556)
Increasing javac's stack size doesn't help. I'm not sure if it's a true infinite loop or the amount of recursion required to terminate is prohibitively high.
The same crash reproduces at least as far back as JDK 8. (I didn't try earlier versions, and reproducing on 8 requires substituting an equivalent definition for List.of)
```
import java.util.List;
class T {
List<M<?, ?>> xs = List.of(new M<>(One.class), new M<>(Two.class), new M<>(Two.class));
}
class M<R extends Eight, I extends Nine<? extends R>> {
M(Class<? extends I> c) {}
}
class One implements Three<Five>, Six<One> {}
class Two implements Four<Seven>, Six<Two> {}
interface Three<R extends Eight> extends Nine<R> {}
interface Four<R extends Eight> extends Nine<R> {}
class Five extends Ten<Five> implements Eleven<Twelve>, Thirteen {}
interface Six<FullKeyT extends TwentyTwo> extends TwentyTwo {}
class Seven extends Ten<Seven> implements Eleven<Fourteen>, Thirteen {}
interface Eight {}
interface Nine<R extends Eight> extends TwentyTwo {}
class Ten<K extends TwentyTwo> implements TwentyTwo {}
interface Eleven<PkT extends Twenty> extends Twenty {}
class Twelve extends Ten<Twelve> implements Eleven<Sixteen>, Thirteen {}
interface Thirteen extends Seventeen {}
class Fourteen extends Ten<Fourteen> implements Eleven<Fifteen>, Thirteen {}
class Fifteen extends Ten<Fifteen> implements Eleven<Twelve>, Thirteen {}
class Sixteen extends Nineteen<Sixteen> implements Eighteen, Thirteen {}
interface Seventeen extends Twenty {}
interface Eighteen extends Twenty {}
class Nineteen<K extends Twenty> extends Ten<K> implements Twenty {}
interface Twenty extends TwentyTwo {}
class TwentyOne<R extends Eight> {}
interface TwentyTwo extends Eight {}
```
$ javac -fullversion T.java |& head -n 30
javac full version "24-ea+7-732"
The system is out of resources.
Consult the following stack trace for details.
java.lang.StackOverflowError
at jdk.compiler/com.sun.tools.javac.code.Types$HashCodeVisitor.visitType(Types.java:4192)
at jdk.compiler/com.sun.tools.javac.code.Types$HashCodeVisitor.visitType(Types.java:4190)
at jdk.compiler/com.sun.tools.javac.code.Type.accept(Type.java:223)
at jdk.compiler/com.sun.tools.javac.code.Types$UnaryVisitor.visit(Types.java:5000)
at jdk.compiler/com.sun.tools.javac.code.Types$HashCodeVisitor.visitClassType(Types.java:4197)
at jdk.compiler/com.sun.tools.javac.code.Types$HashCodeVisitor.visitClassType(Types.java:4190)
at jdk.compiler/com.sun.tools.javac.code.Type$ClassType.accept(Type.java:1053)
at jdk.compiler/com.sun.tools.javac.code.Types$UnaryVisitor.visit(Types.java:5000)
at jdk.compiler/com.sun.tools.javac.code.Types.hashCode(Types.java:4179)
at jdk.compiler/com.sun.tools.javac.code.Types.hashCode(Types.java:4173)
at jdk.compiler/com.sun.tools.javac.code.Types$TypePair.hashCode(Types.java:3855)
at java.base/java.util.HashMap.hash(HashMap.java:338)
at java.base/java.util.HashMap.put(HashMap.java:619)
at java.base/java.util.HashSet.add(HashSet.java:230)
at jdk.compiler/com.sun.tools.javac.code.Types$4.containsTypeRecursive(Types.java:1138)
at jdk.compiler/com.sun.tools.javac.code.Types$4.visitClassType(Types.java:1192)
at jdk.compiler/com.sun.tools.javac.code.Types$4.visitClassType(Types.java:1107)
at jdk.compiler/com.sun.tools.javac.code.Type$ClassType.accept(Type.java:1053)
at jdk.compiler/com.sun.tools.javac.code.Types$DefaultTypeVisitor.visit(Types.java:4920)
at jdk.compiler/com.sun.tools.javac.code.Types.isSubtype(Types.java:1103)
at jdk.compiler/com.sun.tools.javac.code.Types.isSubtype(Types.java:1087)
at jdk.compiler/com.sun.tools.javac.code.Types.isSubtypeNoCapture(Types.java:1077)
at jdk.compiler/com.sun.tools.javac.code.Types$6.visitWildcardType(Types.java:1588)
at jdk.compiler/com.sun.tools.javac.code.Types$6.visitWildcardType(Types.java:1556)