RFR: 8315735: VerifyError when switch statement used with synchronized block
Vicente Romero
vromero at openjdk.org
Wed Sep 6 18:46:40 UTC 2023
On Wed, 6 Sep 2023 09:36:35 GMT, Rémi Forax <forax at openjdk.org> wrote:
>> Having code like:
>>
>> public static void main(String... args) {
>> int i1 = 0 + switch (args.length) {
>> default -> {
>> synchronized (args) {
>> yield 1;
>> }
>> }
>> };
>> }
>>
>>
>> fails with a verification error at runtime. In the classfile, the synchronized block is basically a try-finally (which has an implicit "catch (any)" block), and so it needs the same handling as ordinary try statements.
>>
>> (When there's a try statement inside a switch expression, the pre-existing stack is stored in local variables, and restored at return from the case. This is because catch clauses start with an empty stack.)
>
> src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Gen.java line 1292:
>
>> 1290: hasTry[0] = true;
>> 1291: }
>> 1292:
>
> You can make this code slightly more efficient by using the fact that 'var' is enable to reference the type of an anonymous class.
>
>
> private boolean hasTry(JCSwitchExpression tree) {
> var treeScanner = new TreeScanner() {
> private boolean hasTry;
>
> @Override
> public void visitTry(JCTry tree) {
> hasTry = true;
> }
>
> @Override
> public void visitSynchronized(JCSynchronized tree) {
> hasTry = true;
> }
>
> @Override
> public void visitClassDef(JCClassDecl tree) {
> }
> @Override
> public void visitLambda(JCLambda tree) {
> }
> };
> treeScanner.scan(tree);
> return treeScanner.hasTry;
> }
nice suggestion
-------------
PR Review Comment: https://git.openjdk.org/jdk/pull/15584#discussion_r1317686885
More information about the compiler-dev
mailing list