JDK-8323626 : 4.10.1.2: improve verification typing rules
  • Type: Bug
  • Component: specification
  • Sub-Component: vm
  • Affected Version: 21
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2024-01-11
  • Updated: 2025-06-11
  • Resolved: 2025-06-11
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 25
25Fixed
Related Reports
Relates :  
Description
A review of the typing rules in 4.10.1.2 identified a handful of bugs and stylistic concerns.

- Different (name, loader) pairs that use the same name may refer to the same type, despite using different loaders. In particular, there are many different pairs that represent the same type Object.

- The types 'uninitialized', 'uninitializedThis', and 'null' are not properly introduced.

- A rule should treat an array type as a subtype of any interface type, just as is done for class types

- References to the Java language, such as "Java reference type hierarchy", are distracting and sometimes misleading, and should be removed

- The handling of primitive types byte, char, short, and boolean is imprecise (4.10.1.1 should really be responsible for mapping them all to type 'int')

- The proper term for arrays is usually *component type*, not *element type*

- The rules for 'null' are unnecessarily re-expressed in terms of the Object type

- Subtyping among reference types has more layers than necessary—a single 'isJavaAssignable' predicate (suggest renaming to 'isWideningReference') is sufficient

- There is no need for special subtyping rules to handle primitive types—the reflexive 'isAssignable' rule is sufficient (primitive types are only subtypes of themselves)

Comments
A refinement to class subtyping: in theory it might be nice to determine subtyping between class(Foo,L1) and class(Bar,L2) without having to load both classes. Sometimes, you can load Bar first, and if you're lucky, it is an interface and you're done. Didn't have to load Foo. It doesn't work in the other direction: if you load Foo first, you can consult the list of superclasses, and if none is named Bar, you know Bar is not a superclass. But is Bar an interface? Have to load it to find out. Thus, the 'isWideningReference' rule comparing class types has no reason to avoid loading both classes immediately, simplifying how it is expressed: isWideningReference(class(From, L1), class(To, L2)) :- From \= To, loadedClass(From, L1, FromClass), loadedClass(To, L2, ToClass), loadedSuperclasses(FromClass, Supers), member(ToClass, Supers).
22-02-2025

I've decided this sentence from 4.10.1.2 is benign and should stay to help avoid confusion: "The primitive types byte, char, short, and boolean (field descriptors B, C, S, Z) all correspond to the verification type int."
14-02-2025

Proposed changes are attached, and can be found at https://cr.openjdk.org/~dlsmith/8323626/8323626-20240111/specs/verification-types-jvms.html
12-01-2024