Paul King created GROOVY-11967:
----------------------------------
Summary: VerifyError in @CompileStatic constructor with
default-valued list parameter
Key: GROOVY-11967
URL: https://issues.apache.org/jira/browse/GROOVY-11967
Project: Groovy
Issue Type: Bug
Reporter: Paul King
h3. Summary
A {{@CompileStatic}} class with a constructor that has a default-valued
list-literal parameter triggers {{VerifyError}} when the synthesised
lower-arity bridge constructor is loaded.
h3. Repro
{code:java}
@CompileStatic
class Foo {
Foo(Class<?> a, MessageSource b, List<Class> targetTypes = [Object]) {
}
}
new Foo(String, ms) // boom
{code}
h3. Symptom
{noformat}
java.lang.VerifyError: Bad type on operand stack
Location: Foo.<init>(Ljava/lang/Class;LMessageSource;)V @20: invokevirtual
Reason: Type 'java/lang/Object' (current frame, stack[4]) is not assignable
to 'java/util/ArrayList'
{noformat}
h3. Root cause
Introduced by GROOVY-8699 (commit {{7b18440c4f}}, master only). That change
replaced the {{ScriptBytecodeAdapter.createList(Object[])}} call (returns
{{List}}) with direct {{new ArrayList\(n) + .add(...)}} bytecode, generated by
{{ListExpressionTransformer$NewListExpression.visit()}}.
In indy mode the constructor call lowers to {{invokedynamic
init:(Class;I)Object}} -- the JVM stack value is typed as {{Object}}, so the
subsequent {{INVOKEVIRTUAL java/util/ArrayList.add(Object)Z}} fails
verification because its receiver is not an {{ArrayList}}. The {{CHECKCAST}} to
{{List}} added later by the transformer happens after the {{add}} call, too
late.
h3. Scope
Not specific to {{List<Class>}} -- any default {{[...]}} literal in a
{{@CompileStatic}} constructor is affected ({{List<String>}},
{{List<Integer>}}, {{List<List<String>>}}, etc.). Map defaults go through a
different transformer and are not affected.
h3. Fix
Insert {{CHECKCAST java/util/ArrayList}} immediately after the constructor call
in {{ListExpressionTransformer$NewListExpression.visit()}}, before the loop
that emits the per-element {{DUP / add / pop}}.
h3. Affects
Master only. Groovy 5.0.x and earlier are fine (used the
{{createList(Object[])}} helper).
--
This message was sent by Atlassian Jira
(v8.20.10#820010)