[
https://issues.apache.org/jira/browse/GROOVY-12184?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Paul King resolved GROOVY-12184.
--------------------------------
Fix Version/s: 5.0.8
Resolution: Fixed
> unsound cast for property access on union type (instanceof A || instanceof B)
> throws ClassCastException (fix for GROOVY_5_0_X)
> ------------------------------------------------------------------------------------------------------------------------------
>
> Key: GROOVY-12184
> URL: https://issues.apache.org/jira/browse/GROOVY-12184
> Project: Groovy
> Issue Type: Bug
> Reporter: Paul King
> Assignee: Paul King
> Priority: Major
> Fix For: 5.0.8
>
>
> Under {{@CompileStatic}} (and {{@TypeChecked}}), accessing a property on a
> receiver whose flow-typed type is a union from {{instanceof A || instanceof
> B}} narrows the receiver to the *first* type and emits a hard cast to it.
> When the object is the other type, this throws {{ClassCastException}} at
> runtime.
> {code:groovy}
> import groovy.transform.CompileStatic
> @CompileStatic
> class X1 { Long id }
> @CompileStatic
> class X2 { Long id }
> @CompileStatic
> Long computeId(Object test) {
> if (test instanceof X1 || test instanceof X2) {
> return test.id // narrowed to X1, cast to X1
> }
> null
> }
> assert computeId(new X1(id: 11)) == 11L // ok
> assert computeId(new X2(id: 22)) == 22L // java.lang.ClassCastException:
> class X2 cannot be cast to class X1
> {code}
> *Expected:* both calls return the {{id}} (12 / 22).
> *Actual:* the second call throws {{ClassCastException}}. Reordering the
> {{instanceof}} clauses flips which type fails, confirming the receiver is
> narrowed to a single delegate rather than their common supertype.
> The subscript form ({{test['id']}}) is sound because it routes through
> dynamic {{getAt}} at runtime.
> Affects 4.0.x and 5.0.x (not a regression). Passes on 6.0 (master), fixed
> incidentally by the union/intersection type work in GROOVY-11998.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)