ADDITIONAL SYSTEM INFORMATION :
openjdk 23-ea 2024-09-17
OpenJDK Runtime Environment (build 23-ea+22-1824)
OpenJDK 64-Bit Server VM (build 23-ea+22-1824, mixed mode, sharing)
A DESCRIPTION OF THE PROBLEM :
When using a switch pattern inside a this(...) or super(...) call, the compiler appears to generate invalid bytecode. When trying to load the compiled class a java.lang.VerifyError occurs:
Fehler: Hauptklasse Foo kann nicht initialisiert werden
Ursache: java.lang.VerifyError: Stack map does not match the one at exception handler 72
Exception Details:
Location:
Foo.<init>(Ljava/lang/Object;)V @72: astore_2
Reason:
Type uninitializedThis (current frame, locals[0]) is not assignable to 'Foo' (stack map, locals[0])
Current Frame:
bci: @44
flags: { flagThisUninit }
locals: { uninitializedThis, 'java/lang/Object', 'java/lang/Object', integer, 'Foo$Box' }
stack: { 'java/lang/Throwable' }
Stackmap Frame:
bci: @72
flags: { }
locals: { 'Foo', 'java/lang/Object' }
stack: { 'java/lang/Throwable' }
Bytecode:
0000000: 2a2b 59b8 0001 574d 033e 2c1d ba00 0700
0000010: 00ab 0000 0000 0029 0000 0001 0000 0000
0000020: 0000 0013 2cc0 000b 3a04 1904 b600 0d3a
0000030: 0619 063a 0519 05a7 000b 2c3a 0619 06b6
0000040: 0011 b700 16a7 0011 4dbb 001e 592c b600
0000050: 202c b700 21bf b1
Exception Handler Table:
bci [44, 47] => handler: 72
Stackmap Table:
full_frame(@10,{UninitializedThis,Object[#18],Object[#18],Integer},{UninitializedThis})
same_locals_1_stack_item_frame(@36,UninitializedThis)
same_locals_1_stack_item_frame(@58,UninitializedThis)
full_frame(@66,{UninitializedThis,Object[#18]},{UninitializedThis,Object[#45]})
full_frame(@72,{Object[#23],Object[#18]},{Object[#28]})
same_frame(@86)
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Compile the attached source file with javac
2. Run the compiled class with java
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The program should complete normally without any output.
ACTUAL -
see description
---------- BEGIN SOURCE ----------
class Foo {
public static void main(String[] args) {
// do nothing
}
public Foo(Object obj) {
this(switch (obj) {
case Box(var string) -> string;
case Object o -> o.toString();
});
}
public Foo(String foo) {}
record Box(String message) {}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Extracting the switch expression into a static method avoids the problem.
FREQUENCY : always
openjdk 23-ea 2024-09-17
OpenJDK Runtime Environment (build 23-ea+22-1824)
OpenJDK 64-Bit Server VM (build 23-ea+22-1824, mixed mode, sharing)
A DESCRIPTION OF THE PROBLEM :
When using a switch pattern inside a this(...) or super(...) call, the compiler appears to generate invalid bytecode. When trying to load the compiled class a java.lang.VerifyError occurs:
Fehler: Hauptklasse Foo kann nicht initialisiert werden
Ursache: java.lang.VerifyError: Stack map does not match the one at exception handler 72
Exception Details:
Location:
Foo.<init>(Ljava/lang/Object;)V @72: astore_2
Reason:
Type uninitializedThis (current frame, locals[0]) is not assignable to 'Foo' (stack map, locals[0])
Current Frame:
bci: @44
flags: { flagThisUninit }
locals: { uninitializedThis, 'java/lang/Object', 'java/lang/Object', integer, 'Foo$Box' }
stack: { 'java/lang/Throwable' }
Stackmap Frame:
bci: @72
flags: { }
locals: { 'Foo', 'java/lang/Object' }
stack: { 'java/lang/Throwable' }
Bytecode:
0000000: 2a2b 59b8 0001 574d 033e 2c1d ba00 0700
0000010: 00ab 0000 0000 0029 0000 0001 0000 0000
0000020: 0000 0013 2cc0 000b 3a04 1904 b600 0d3a
0000030: 0619 063a 0519 05a7 000b 2c3a 0619 06b6
0000040: 0011 b700 16a7 0011 4dbb 001e 592c b600
0000050: 202c b700 21bf b1
Exception Handler Table:
bci [44, 47] => handler: 72
Stackmap Table:
full_frame(@10,{UninitializedThis,Object[#18],Object[#18],Integer},{UninitializedThis})
same_locals_1_stack_item_frame(@36,UninitializedThis)
same_locals_1_stack_item_frame(@58,UninitializedThis)
full_frame(@66,{UninitializedThis,Object[#18]},{UninitializedThis,Object[#45]})
full_frame(@72,{Object[#23],Object[#18]},{Object[#28]})
same_frame(@86)
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Compile the attached source file with javac
2. Run the compiled class with java
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The program should complete normally without any output.
ACTUAL -
see description
---------- BEGIN SOURCE ----------
class Foo {
public static void main(String[] args) {
// do nothing
}
public Foo(Object obj) {
this(switch (obj) {
case Box(var string) -> string;
case Object o -> o.toString();
});
}
public Foo(String foo) {}
record Box(String message) {}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Extracting the switch expression into a static method avoids the problem.
FREQUENCY : always