You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@groovy.apache.org by "Eric Milles (Jira)" <ji...@apache.org> on 2025/10/12 22:25:00 UTC

[jira] [Updated] (GROOVY-11769) @CompileStatic incorrectly generates dynamic call for a cast guarded by an instanceof check

     [ https://issues.apache.org/jira/browse/GROOVY-11769?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Eric Milles updated GROOVY-11769:
---------------------------------
    Fix Version/s: 5.0.0
                       (was: 4.0.28)

> @CompileStatic incorrectly generates dynamic call for a cast guarded by an instanceof check
> -------------------------------------------------------------------------------------------
>
>                 Key: GROOVY-11769
>                 URL: https://issues.apache.org/jira/browse/GROOVY-11769
>             Project: Groovy
>          Issue Type: Bug
>    Affects Versions: 4.0.28
>         Environment: JDK21
>            Reporter: Val E
>            Assignee: Eric Milles
>            Priority: Minor
>             Fix For: 5.0.0
>
>         Attachments: CompilerTest.groovy, decompiled.java
>
>
> When using {{@CompileStatic}} the compiler fails to generate static bytecode for a cast on a variable of type {{{}Object{}}}. Even when the cast is explicitly guarded by an {{instanceof Collection}} check, the compiler pessimistically inserts an {{invokedynamic}} call when the variable is passed as an argument to a method (like {{{}list.addAll(){}}}) or a constructor ({{{}new ArrayList(){}}}).
> This behavior defeats the purpose of the explicit {{instanceof}} guard and explicit cast
> Ex groovy method
> {code:java}
> static List<Object> resultToResultList(Object result) {
>     if (result == null) return new ArrayList()
>     else if (result instanceof Collection)return new ArrayList<Object>((Collection)result)
>     else if( result instanceof Number) List.of(result)
>     else if( result instanceof String) List.of(result)
>     return List.of(result)
> }{code}
> the decompiled version of the same method, note the dynamic dipatch casting on Collection
> {code:java}
> public static List<Object> resultToResultList(Object result) {
>     if (result == null) {
>         return new ArrayList();
>     } else if (result instanceof Collection) {
>         return new ArrayList(((Class)result).cast<invokedynamic>(result));
>     } else {
>         if (result instanceof Number) {
>             List.of(result);
>         } else if (result instanceof String) {
>             List.of(result);
>         }
>         return List.of(result);
>     }
> } {code}



--
This message was sent by Atlassian Jira
(v8.20.10#820010)