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