Unchecked cast unchecked?
Maurizio Cimadamore
maurizio.cimadamore at oracle.com
Wed Oct 30 10:17:18 UTC 2024
Good catch - I believe the compiler does what it does because it uses
the type of the cast (as well as the types of the aruments) to determine
the final compile-time type of the method being called. This is the type
that will (under erasure) be reified in the constant pool. So, here
javac sees a call to a method that returns V and then a cast to V...
Ideally javac should erase things earlier, or just use Object as the
type of the method call, as Alex suggests. The latter might be slightly
complicated because, after we added VarHandle support in Java 9, we also
have some polymorphic methods whose return type is not Object (see
VarHandle::compareAndSet). But, basically, javac should implement this
more closely, w/o getting too distracted by the type inferred for the
synthetic symbol attached to the method call AST node:
> The compile-time result is determined as follows:
>
> *
>
> If the signature polymorphic method is either |void| or has a
> return type other than |Object|, the compile-time result is the
> result of the invocation type of the compile-time declaration
> (§15.12.2.6
> <https://docs.oracle.com/javase/specs/jls/se15/html/jls-15.html#jls-15.12.2.6>).
>
>
> *
>
> Otherwise, if the method invocation expression is an expression
> statement, the compile-time result is |void|.
>
> *
>
> Otherwise, if the method invocation expression is the operand of a
> cast expression (§15.16
> <https://docs.oracle.com/javase/specs/jls/se15/html/jls-15.html#jls-15.16>),
> the compile-time result is the erasure of the type of the cast
> expression (§4.6
> <https://docs.oracle.com/javase/specs/jls/se15/html/jls-4.html#jls-4.6>).
>
> *
>
> Otherwise, the compile-time result is the signature polymorphic
> method's return type, |Object|.
>
Filed:
https://bugs.openjdk.org/browse/JDK-8343286
Cheers
Maurizio
On 29/10/2024 22:52, Alex Buckley wrote:
> VarHandle::getAndSet(Object[]) is a signature polymorphic method,
> which means that the type of a method call is sensitive to an ensuing
> cast:
>
> "... if the method invocation expression is the operand of a cast
> expression (§15.16), the compile-time result is the erasure of the
> type of the cast expression (§4.6)." (JLS 15.12.3)
>
> This has implications for how the method call is compiled, but it's
> moot for your program because the type of the method call is Object no
> matter how you slice it.
>
> Casting from Object to type variable V is achieved by a narrowing
> reference conversion that is unchecked. So, I'd expect an "unchecked
> cast" warning, like for a non-signature polymorphic method.
>
> Alex
>
> On 10/29/2024 2:30 PM, Archie Cobbs wrote:
>> Question: Should this program generate an unchecked cast warning?
>>
>> import java.lang.invoke.VarHandle;
>> class VarHandleCast<V> {
>> VarHandle vh;
>> V method(Object obj) {
>> return (V)vh.getAndSet(this, obj); // unchecked cast?
>> }
>> }
>>
>> Currently, it does not.
>>
>> Presumably that has something to do with this code in Types.java but
>> I'm not sure why this would mean there should be no warning:
>>
>> /**
>> * A polymorphic signature method (JLS 15.12.3) is a method that
>> * (i) is declared in the
>> java.lang.invoke.MethodHandle/VarHandle classes;
>> * (ii) takes a single variable arity parameter;
>> * (iii) whose declared type is Object[];
>> * (iv) has any return type, Object signifying a polymorphic
>> return type; and
>> * (v) is native.
>> */
>> public boolean isSignaturePolymorphic(MethodSymbol msym) {
>> List<Type> argtypes = msym.type.getParameterTypes();
>> return (msym.flags_field & NATIVE) != 0 &&
>> (msym.owner == syms.methodHandleType.tsym ||
>> msym.owner == syms.varHandleType.tsym) &&
>> argtypes.length() == 1 &&
>> argtypes.head.hasTag(TypeTag.ARRAY) &&
>> ((ArrayType)argtypes.head).elemtype.tsym ==
>> syms.objectType.tsym;
>> }
>>
>> Thanks,
>> -Archie
>>
>> --
>> Archie L. Cobbs
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/compiler-dev/attachments/20241030/9e1229ac/attachment-0001.htm>
More information about the compiler-dev
mailing list