RFR: 8330387: Crash with a different types patterns (primitive vs generic) in instanceof
Aggelos Biboudis
abimpoudis at openjdk.org
Wed Apr 17 13:18:09 UTC 2024
Prior to this PR those three tests were accepted correctly (and still do). However the conversion after unboxing was unconditionally exact so no further test was generated. The first two cover a widening reference conversion followed by unboxing and the third a widening reference conversion followed by unboxing followed by a widening primitive primitive conversion (which was unconditionally exact, notice `int` to `double`).
public static <T extends Integer> boolean wideningReferenceConversionUnboxing(T i) {
return i instanceof int ii;
}
public static <T extends Byte> boolean wideningReferenceConversionUnboxing2(T i) {
return i instanceof byte bb;
}
public static <T extends Integer> boolean wideningReferenceConversionUnboxingAndWideningPrimitive(T i) {
return i instanceof double ii;
}
What was missing was a widening reference conversion followed by unboxing followed by widening primitive conversion that was not unconditionally exact. `int` to `float` is a widening primitive conversion that is possibly not exact.
public static <T extends Integer> boolean wideningReferenceConversionUnboxing3(T i) {
return i instanceof float ff;
}
That reveals that the type of the synthetic variable prior to binding needed to be erased to a type. After Lowering:
public static boolean wideningReferenceConversionUnboxing(Integer i) {
return (let int ii in (let /*synthetic*/ final Integer tmp4646$ = i in tmp4646$ != null) && (let ii = (int)i.intValue(); in true));
}
public static boolean wideningReferenceConversionUnboxing2(Byte i) {
return (let byte bb in (let /*synthetic*/ final Byte tmp4776$ = i in tmp4776$ != null) && (let bb = (byte)i.byteValue(); in true));
}
public static boolean wideningReferenceConversionUnboxing3(Integer i) {
return (let float ff in (let /*synthetic*/ final Integer tmp4910$ = i in tmp4910$ != null && java.lang.runtime.ExactConversionsSupport.isIntToFloatExact(tmp4910$.intValue())) && (let ff = (float)i.intValue(); in true));
}
public static boolean wideningReferenceConversionUnboxingAndWideningPrimitive(Integer i) {
return (let double ii in (let /*synthetic*/ final Integer tmp5064$ = i in tmp5064$ != null) && (let ii = (double)i.intValue(); in true));
}
-------------
Commit messages:
- 8330387: Crash with a different types patterns (primitive vs generic) in instanceof
Changes: https://git.openjdk.org/jdk/pull/18811/files
Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=18811&range=00
Issue: https://bugs.openjdk.org/browse/JDK-8330387
Stats: 27 lines in 6 files changed: 21 ins; 0 del; 6 mod
Patch: https://git.openjdk.org/jdk/pull/18811.diff
Fetch: git fetch https://git.openjdk.org/jdk.git pull/18811/head:pull/18811
PR: https://git.openjdk.org/jdk/pull/18811
More information about the compiler-dev
mailing list