Integrated: 8332106: VerifyError when using switch pattern in this(...) or super(...)
Jan Lahoda
jlahoda at openjdk.org
Fri May 24 06:30:12 UTC 2024
On Mon, 13 May 2024 14:37:49 GMT, Jan Lahoda <jlahoda at openjdk.org> wrote:
> Considering code like:
>
> public class Test {
>
> public Test(int i) {
> }
>
> public Test(Object o) {
> this(o instanceof R(String s) ? s.length() : -1);
> }
>
> public static void main(String... args) {}
>
> record R(String s) {}
> }
>
>
> Running this crashes:
>
> $ java .../Test.java
> Exception in thread "main" java.lang.VerifyError: Stack map does not match the one at exception handler 36
> Exception Details:
> Location:
> Test.<init>(Ljava/lang/Object;)V @36: astore_2
> Reason:
> Type uninitializedThis (current frame, locals[0]) is not assignable to 'Test' (stack map, locals[0])
> Current Frame:
> bci: @14
> flags: { flagThisUninit }
> locals: { uninitializedThis, 'java/lang/Object', top, 'Test$R' }
> stack: { 'java/lang/Throwable' }
> Stackmap Frame:
> bci: @36
> flags: { }
> locals: { 'Test', 'java/lang/Object' }
> stack: { 'java/lang/Throwable' }
> Bytecode:
> 0000000: 2a2b c100 0799 0018 2bc0 0007 4e2d b600
> 0000010: 093a 0419 044d 2cb6 000d a700 0402 b700
> 0000020: 13a7 0011 4dbb 001a 592c b600 1c2c b700
> 0000030: 1fbf b1
> Exception Handler Table:
> bci [14, 17] => handler: 36
> Stackmap Table:
> same_locals_1_stack_item_frame(@29,UninitializedThis)
> full_frame(@30,{UninitializedThis,Object[#2]},{UninitializedThis,Integer})
> full_frame(@36,{Object[#20],Object[#2]},{Object[#24]})
> same_frame(@50)
>
> at java.base/java.lang.Class.forName0(Native Method)
> at java.base/java.lang.Class.forName(Class.java:534)
> at java.base/java.lang.Class.forName(Class.java:513)
> at jdk.compiler/com.sun.tools.javac.launcher.Main.execute(Main.java:432)
> at jdk.compiler/com.sun.tools.javac.launcher.Main.run(Main.java:208)
> at jdk.compiler/com.sun.tools.javac.launcher.Main.main(Main.java:135)
>
>
> The reason is that there is a synthetic catch generated wrapping the record accessors inside the pattern matching. The range where the exception this catch is catching is before the real `this(...)` `invokespecial`, and hence the `this` is still an "uninitialized this". But the code for the catch is generated at the end of the constructor, when `this` is already initialized, and javac generates the stack maps as if `this` was initialized.
>
> In general, the pattern matching code can be both before and after the `this` has been initialized. But, I don't think a stack map frame can be generated for the handler originating in places with both "uninitialized this " and (...
This pull request has now been integrated.
Changeset: af056c16
Author: Jan Lahoda <jlahoda at openjdk.org>
URL: https://git.openjdk.org/jdk/commit/af056c1676dab3b0b35666a8259db60f9bbf824e
Stats: 454 lines in 3 files changed: 439 ins; 4 del; 11 mod
8332106: VerifyError when using switch pattern in this(...) or super(...)
Reviewed-by: abimpoudis, vromero
-------------
PR: https://git.openjdk.org/jdk/pull/19217
More information about the compiler-dev
mailing list