On Wed, 7 May 2025 11:57:02 GMT, Aggelos Biboudis <abimpou...@openjdk.org> wrote:
> While the compiler does not allow invalid queries to flow into > `SwitchBootstraps:typeSwitch`, a library user could do that and `typeSwitch` > does not prevent such usage pattern errors resulting in erroneous evaluation. > > For example this is not valid Java (and protected) by javac: > > > byte b = 1; > switch (b) { > case String s -> System.out.println("How did we get here? byte is " + > s.getClass()); > } > > > but this is a valid call (and not protected): > > > CallSite shortSwitch = SwitchBootstraps.typeSwitch( > MethodHandles.lookup(), > "", > MethodType.methodType(int.class, short.class, int.class), // models > (short, int) -> int > String.class); > > > The `SwitchBootstraps.typeSwitch` returns wrong result since the code was > reasoning erroneously that this pair was unconditionally exact. > > This PR proposes to add the safety check in unconditional exactness which > will return false in erroneous pairs and then the actual check will be > delegated to `instanceof`. For the case of erroneous pairs with primitive > `boolean`s there is a check in the beginning of the type switch skeleton. src/java.base/share/classes/java/lang/runtime/SwitchBootstraps.java line 725: > 723: > 724: private static boolean isNotValidPair(Class<?> selectorType, Object > caseLabel) { > 725: return (selectorType == boolean.class && caseLabel != > boolean.class && caseLabel != Boolean.class) || What happens if `caseLabel` is a reference class? E.g. a `boolean` selector is incompatible with `String`. src/java.base/share/classes/java/lang/runtime/SwitchBootstraps.java line 786: > 784: (selectorType.equals(char.class) && > (selectorWrapper.isStrictSubRangeOf(targetWrapper))) || > 785: (selectorType.equals(int.class) && > (targetType.equals(double.class) || targetType.equals(long.class))) || > 786: (selectorType.equals(float.class) && > (selectorWrapper.isStrictSubRangeOf(targetWrapper)))))) return true; Is `double` the only allowed target for `float` ? If so, perhaps we could simplify like for other selector types. Or, alternatively, I wonder if it wouldn't be simpler to _always_ check for strict subrange on the wrappers, but then ban the conversions that are not exact (e.g. int -> float), as those are few? ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/25090#discussion_r2084222014 PR Review Comment: https://git.openjdk.org/jdk/pull/25090#discussion_r2084221014