widen-unbox-widen vs JEP 455
Angelos Bimpoudis
angelos.bimpoudis at oracle.com
Fri Sep 13 08:50:57 UTC 2024
Hello Stephan,
Thank you for your feedback and investigation!
Let me recap.
Currently (and correctly) the following two examples work as expected.
```java
Short s = 42;
s instanceof int
// true, because s has static type Short followed by unboxing followed by w.p.c.
Object o = s;
o instanceof int
// false, because o has static type Object followed by narrowing r.c.
// (to Integer, thus false) followed by unboxing
```
However, we realized that javac accepts the following two with
different runtime behavior. In the first case javac loses the static type of
`ls.get(0)`. This has the effect to "guide" the conversion checking not from
`Short` to `int` as expected, but from `Object` to `int`. In the second case
javac inserts a sharp cast in the selector type `(Short) ls.get(0)`.
```java
List<Short> ls = List.of((short) 42);
ls.get(0) instanceof int
// false, since what is executed is ((Object) ls.get(0)) instanceof int
switch(ls.get(0)) {
case int _ -> true;
default -> false;
}
// true, since what is executed is ((Short) ls.get(0))
```
(of course, if we would have `List<?>` both return `false`, as expected)
There are two requirements here. `instanceof` is the precondition of safe
casting and safe casting is described in Section 5.5. The second is that
`switch` and `instanceof` should expose the same behaviour.
As your example clearly demonstrates, javac fails to respect this second
requirement. We will address that in javac and add any required JLS
clarification as part of JEP 455 (Preview 2).
Many many thanks!
________________________________
From: compiler-dev <compiler-dev-retn at openjdk.org> on behalf of Stephan Herrmann <stephan.herrmann at berlin.de>
Sent: 10 September 2024 14:40
To: compiler-dev at openjdk.org <compiler-dev at openjdk.org>
Subject: Re: widen-unbox-widen vs JEP 455
Has anyone found the time to check which outcome is intended according to JEP 455?
Do I understand correctly, that the pattern 'int i' should always match at
runtime in all cases of the below code?
Alternatively, should we propose to drop the rules for widen-then-unbox
conversions, because any real benefit of such conversion would require that
'final' is dropped from any of the boxing classes?
thanks,
Stephan
Am 01.09.24 um 10:44 schrieb Stephan Herrmann:
> I just learned that reference widening followed by unboxing (followed by
> primitive widening) is deemed a relevant conversion [1]. So I made sure that ecj
> can handle this in various situation, only to find out that this will make ecj
> produce code that is behaviorally different from what javac emits.
>
> Here's my test code challenging this aspect of JEP 455:
> //
> <T extends Short> void typeVariableSingle(T single) {
> int i1 = single;
> System.out.print(i1);
> if (single instanceof int i)
> System.out.print(i);
> else
> System.out.print('-');
> switch (single) {
> case int i -> System.out.print(i);
> default -> System.out.print('-');
> }
> System.out.println();
> }
> <T extends Short> void typeVariableList(List<T> list) {
> int i1 = list.get(0);
> System.out.print(i1);
> if (list.get(0) instanceof int i)
> System.out.print(i);
> else
> System.out.print('-');
> switch (list.get(0)) {
> case int i -> System.out.print(i);
> default -> System.out.print('-');
> }
> System.out.println();
> }
> void wildcard(List<? extends Short> list) {
> int i1 = list.get(0);
> System.out.print(i1);
> if (list.get(0) instanceof int i)
> System.out.print(i);
> else
> System.out.print('-');
> switch (list.get(0)) {
> case int i -> System.out.print(i);
> default -> System.out.print('-');
> }
> System.out.println();
> }
> void main() {
> Short s = 1;
> typeVariableSingle(s);
> typeVariableList(Collections.singletonList(s));
> wildcard(Collections.singletonList(s));
> }
> //
>
> compiled with ecj this gives
> 111
> 111
> 111
>
> compiled with javac the program prints
> 111
> 1-1
> 1-1
>
> Is this a simple bug in javac, or is there more to it?
> thanks
> Stephan
>
> [1] see answers to
> https://mail.openjdk.org/pipermail/amber-spec-experts/2024-August/004204.html
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/compiler-dev/attachments/20240913/05d792d5/attachment-0001.htm>
More information about the compiler-dev
mailing list