JDK-8324809 : compiler can crash with SOE while proving if two recursive types are disjoint
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 8-pool,11,17,21,22,23
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2024-01-22
  • Updated: 2024-05-23
  • Resolved: 2024-05-17
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 23
23 b24Fixed
Description
ADDITIONAL SYSTEM INFORMATION :
window11, win10

A DESCRIPTION OF THE PROBLEM :
when run javac compile flow code, get stackoverflow error

i try to 1.8.0_271 and 17.0.8, the same error throwed
---------------
package test;
import java.io.Serializable;

import test.Criteria.Builder;

@SuppressWarnings({ "unchecked", "rawtypes" })
public class Criteria<B extends Builder<? extends Criteria>> implements Serializable {

	private static final long serialVersionUID = 5066371601838698479L;

	protected Criteria() {}

	protected Criteria(B builder) {

	}

	public static <B extends Builder<E>, E extends Criteria<B>> B builder() {
		return (B) new Builder<>();
	}

	public static class Builder<C extends Criteria<? extends Builder<C>>> {


		protected Builder() {
		}

		public Builder<C> page() {
			return this;
		}

		public C build() {
			return (C) new Criteria<Builder<C>>(this);
		}
	}
}




REGRESSION : Last worked in version 17.0.10

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
compile pre code

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
get compiled class
ACTUAL -
D:\workspace>E:\devProgram\jdk17\bin\javac.exe Criteria.java


系统资源不足。
有关详细信息, 请参阅以下堆栈跟踪。
java.lang.StackOverflowError
        at jdk.compiler/com.sun.tools.javac.code.Type.equalsIgnoreMetadata(Type.java:513)
        at jdk.compiler/com.sun.tools.javac.code.Type$ClassType.contains(Type.java:1150)
        at jdk.compiler/com.sun.tools.javac.code.Types$Rewriter.visitTypeVar(Types.java:4769)
        at jdk.compiler/com.sun.tools.javac.code.Types$Rewriter.visitTypeVar(Types.java:4724)
        at jdk.compiler/com.sun.tools.javac.code.Type$TypeVar.accept(Type.java:1681)
        at jdk.compiler/com.sun.tools.javac.code.Types$UnaryVisitor.visit(Types.java:4980)
        at jdk.compiler/com.sun.tools.javac.code.Types$Rewriter.visitClassType(Types.java:4739)
        at jdk.compiler/com.sun.tools.javac.code.Types$Rewriter.visitClassType(Types.java:4724)
        at jdk.compiler/com.sun.tools.javac.code.Type$ClassType.accept(Type.java:1011)
        at jdk.compiler/com.sun.tools.javac.code.Types$UnaryVisitor.visit(Types.java:4980)
        at jdk.compiler/com.sun.tools.javac.code.Types$Rewriter.visitTypeVar(Types.java:4771)
        at jdk.compiler/com.sun.tools.javac.code.Types$Rewriter.visitTypeVar(Types.java:4724)
        at jdk.compiler/com.sun.tools.javac.code.Type$TypeVar.accept(Type.java:1681)
        at jdk.compiler/com.sun.tools.javac.code.Types$UnaryVisitor.visit(Types.java:4980)
        at jdk.compiler/com.sun.tools.javac.code.Types$Rewriter.visitClassType(Types.java:4739)
        at jdk.compiler/com.sun.tools.javac.code.Types$Rewriter.visitClassType(Types.java:4724)
        at jdk.compiler/com.sun.tools.javac.code.Type$ClassType.accept(Type.java:1011)
        at jdk.compiler/com.sun.tools.javac.code.Types$UnaryVisitor.visit(Types.java:4980)
        at jdk.compiler/com.sun.tools.javac.code.Types$Rewriter.visitTypeVar(Types.java:4771)
        at jdk.compiler/com.sun.tools.javac.code.Types$Rewriter.visitTypeVar(Types.java:4724)
        at jdk.compiler/com.sun.tools.javac.code.Type$TypeVar.accept(Type.java:1681)

---------- BEGIN SOURCE ----------
package test;
import java.io.Serializable;

import test.Criteria.Builder;

@SuppressWarnings({ "unchecked", "rawtypes" })
public class Criteria<B extends Builder<? extends Criteria>> implements Serializable {

	private static final long serialVersionUID = 5066371601838698479L;

	protected Criteria() {}

	protected Criteria(B builder) {

	}

	public static <B extends Builder<E>, E extends Criteria<B>> B builder() {
		return (B) new Builder<>();
	}

	public static class Builder<C extends Criteria<? extends Builder<C>>> {


		protected Builder() {
		}

		public Builder<C> page() {
			return this;
		}

		public C build() {
			return (C) new Criteria<Builder<C>>(this);
		}
	}
}

---------- END SOURCE ----------

FREQUENCY : always



Comments
Changeset: 39a55e97 Author: Vicente Romero <vromero@openjdk.org> Date: 2024-05-17 14:16:11 +0000 URL: https://git.openjdk.org/jdk/commit/39a55e97799b5328da85aaa66c8d23175b305691
17-05-2024

A pull request was submitted for review. URL: https://git.openjdk.org/jdk/pull/19194 Date: 2024-05-11 22:18:12 +0000
11-05-2024

minimal reproductor: class Criteria<B extends Builder<? extends Criteria>> { public <D extends Builder<E>, E extends Criteria<D>> D builder() { return (D) new Builder<>(); } } class Builder<C extends Criteria<? extends Builder<C>>> {}
18-04-2024

Additional Information from submitter: ============================ change method Criteria.builder() define to following code --- public static <B extends Builder<E>, E extends Criteria<B>> B builder() { return (B) new Builder<>(); } --- it will be compile success
30-01-2024

The issue is reproducible with JDK 8 through JDK 22. > javac .\Criteria.java 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$Rewriter.visitTypeVar(Types.java:4762) at jdk.compiler/com.sun.tools.javac.code.Types$Rewriter.visitTypeVar(Types.java:4718) at jdk.compiler/com.sun.tools.javac.code.Type$TypeVar.accept(Type.java:1705) at jdk.compiler/com.sun.tools.javac.code.Types$UnaryVisitor.visit(Types.java:4974) at jdk.compiler/com.sun.tools.javac.code.Types$Rewriter.visitClassType(Types.java:4733) at jdk.compiler/com.sun.tools.javac.code.Types$Rewriter.visitClassType(Types.java:4718) at jdk.compiler/com.sun.tools.javac.code.Type$ClassType.accept(Type.java:1050) at jdk.compiler/com.sun.tools.javac.code.Types$UnaryVisitor.visit(Types.java:4974) at jdk.compiler/com.sun.tools.javac.code.Types$Rewriter.visitTypeVar(Types.java:4765) at jdk.compiler/com.sun.tools.javac.code.Types$Rewriter.visitTypeVar(Types.java:4718) at jdk.compiler/com.sun.tools.javac.code.Type$TypeVar.accept(Type.java:1705) at jdk.compiler/com.sun.tools.javac.code.Types$UnaryVisitor.visit(Types.java:4974) at jdk.compiler/com.sun.tools.javac.code.Types$Rewriter.visitClassType(Types.java:4733) at jdk.compiler/com.sun.tools.javac.code.Types$Rewriter.visitClassType(Types.java:4718) at jdk.compiler/com.sun.tools.javac.code.Type$ClassType.accept(Type.java:1050) at jdk.compiler/com.sun.tools.javac.code.Types$UnaryVisitor.visit(Types.java:4974) at jdk.compiler/com.sun.tools.javac.code.Types$Rewriter.visitTypeVar(Types.java:4765) at jdk.compiler/com.sun.tools.javac.code.Types$Rewriter.visitTypeVar(Types.java:4718) at jdk.compiler/com.sun.tools.javac.code.Type$TypeVar.accept(Type.java:1705) at jdk.compiler/com.sun.tools.javac.code.Types$UnaryVisitor.visit(Types.java:4974) at jdk.compiler/com.sun.tools.javac.code.Types$Rewriter.visitClassType(Types.java:4733) at jdk.compiler/com.sun.tools.javac.code.Types$Rewriter.visitClassType(Types.java:4718) at jdk.compiler/com.sun.tools.javac.code.Type$ClassType.accept(Type.java:1050)
29-01-2024