On Wed, 7 May 2025 11:57:02 GMT, Aggelos Biboudis <[email protected]>
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