-
Bug
-
Resolution: Fixed
-
P3
-
16, 17, 19, 20, 21
-
b03
-
generic
-
generic
Issue | Fix Version | Assignee | Priority | Status | Resolution | Resolved In Build |
---|---|---|---|---|---|---|
JDK-8311328 | 21.0.1 | Jan Lahoda | P3 | Resolved | Fixed | b02 |
JDK-8310504 | 21 | Jan Lahoda | P3 | Resolved | Fixed | b29 |
Same result was obtained when testing under OSX/ARM64.
A DESCRIPTION OF THE PROBLEM :
When a Java method contains a labeled if condition with an instanceof pattern matching condition and then in the body does a break using that label, the compiler doesn't complain if any successor statements dereference the pattern variable. The produced code is illegal and results in a VerifyError when executed in the JVM.
The simple example under "Source code for an executable test case results in the following error when compiled and executed:
Error: Unable to initialize main class T
Caused by: java.lang.VerifyError: Bad local variable type
Exception Details:
Location:
T.main([Ljava/lang/String;)V @18: aload_2
Reason:
Type top (current frame, locals[2]) is not assignable to reference type
Current Frame:
bci: @18
flags: { }
locals: { '[Ljava/lang/String;', 'java/lang/Object' }
stack: { 'java/io/PrintStream' }
Bytecode:
0000000: 1207 4c2b c100 0999 0008 2bc0 0009 4db2
0000010: 000b 2cb6 0011 b1
Stackmap Table:
append_frame(@15,Object[#2])
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Compile and execute the example class provided in "Source code for an executable test case".
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The code should fail to compile, because when breaking out of the if body the object `o` tested with instanceof is known not to be of type String and the pattern variable `s` should therefore not be dereferencable.
ACTUAL -
The code is compiled successfully (javap output pasted below) but fails to run in the JVM.
public static void main(java.lang.String[]);
Code:
0: ldc #7 // String hello
2: astore_1
3: aload_1
4: instanceof #9 // class java/lang/String
7: ifeq 15
10: aload_1
11: checkcast #9 // class java/lang/String
14: astore_2
15: getstatic #11 // Field java/lang/System.out:Ljava/io/PrintStream;
18: aload_2
19: invokevirtual #17 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
22: return
---------- BEGIN SOURCE ----------
class T {
public static void main(String[] args) {
Object o = "hello";
X: if (!(o instanceof String s)) {
break X;
}
System.out.println(s);
}
}
---------- END SOURCE ----------
FREQUENCY : always
- backported by
-
JDK-8310504 Illegal bytecode for break from if with instanceof pattern matching condition
- Resolved
-
JDK-8311328 Illegal bytecode for break from if with instanceof pattern matching condition
- Resolved
- csr for
-
JDK-8310016 Illegal bytecode for break from if with instanceof pattern matching condition
- Closed
- relates to
-
JDK-8305701 6.3.2: Incomplete specification of flow scoping
- Resolved
- links to
-
Commit openjdk/jdk21/789b2fc4
-
Commit openjdk/jdk/a15db1a5
-
Review openjdk/jdk21/47
-
Review openjdk/jdk/14517