diff options
author | 2022-12-09 17:40:28 +0000 | |
---|---|---|
committer | 2022-12-12 13:33:39 +0000 | |
commit | 5a454c6ed6bb692f5881a68ea9177d50e735b101 (patch) | |
tree | e1207f5eb3528e939c8e6580dd1524aa5bb93367 | |
parent | 5d3a23dd7d288b98a0713289072db785d01615c8 (diff) |
Fix missing ClassCastException in VH unboxing conversion
Fix: 261589198
Test: art/test/run-test --host 712
Test: art/test/run-test --jvm 712
Test: art/test.py --host
Test: art/tools/run-libcore-tests.sh --mode host libcore.java.lang.invoke
Test: art/tools/run-libcore-tests.sh --mode host test.java.lang.invoke
Change-Id: I1cb085e509cc83b89a6a8e101802a3ae8cc7e758
-rw-r--r-- | runtime/method_handles.cc | 7 | ||||
-rw-r--r-- | runtime/method_handles_test.cc | 2 | ||||
-rw-r--r-- | test/712-varhandle-invocations/src/VarHandleTypeConversionTests.java | 46 |
3 files changed, 54 insertions, 1 deletions
diff --git a/runtime/method_handles.cc b/runtime/method_handles.cc index a992af0cc1..059a33f079 100644 --- a/runtime/method_handles.cc +++ b/runtime/method_handles.cc @@ -290,6 +290,13 @@ bool ConvertJValueCommon( return false; } + ObjPtr<mirror::Class> from_obj_type = from_obj->GetClass(); + Primitive::Type from_primitive_type; + if (!GetUnboxedPrimitiveType(from_obj_type, &from_primitive_type)) { + ThrowClassCastException(from, to); + return false; + } + Primitive::Type unboxed_type; JValue unboxed_value; if (UNLIKELY(!GetUnboxedTypeAndValue(from_obj, &unboxed_type, &unboxed_value))) { diff --git a/runtime/method_handles_test.cc b/runtime/method_handles_test.cc index fb2f7bd5c8..588f8612d0 100644 --- a/runtime/method_handles_test.cc +++ b/runtime/method_handles_test.cc @@ -347,7 +347,7 @@ TEST_F(MethodHandlesTest, UnsupportedNotBoxReferenceToPrimitiveConversion) { value.SetL(cl->FindPrimitiveClass('V')); ASSERT_FALSE(TryConversion(soa.Self(), from, to, &value)); ASSERT_TRUE(soa.Self()->IsExceptionPending()); - ASSERT_TRUE(IsWrongMethodTypeException(soa.Self()->GetException())); + ASSERT_TRUE(IsClassCastException(soa.Self()->GetException())); soa.Self()->ClearException(); } diff --git a/test/712-varhandle-invocations/src/VarHandleTypeConversionTests.java b/test/712-varhandle-invocations/src/VarHandleTypeConversionTests.java index 73e3044fa5..51c3b95a9e 100644 --- a/test/712-varhandle-invocations/src/VarHandleTypeConversionTests.java +++ b/test/712-varhandle-invocations/src/VarHandleTypeConversionTests.java @@ -54,6 +54,52 @@ public class VarHandleTypeConversionTests { } } + public static class ReferenceReturnTypeTest extends VarHandleUnitTest { + private Object o; + private static final VarHandle vh; + + static { + try { + Class<?> cls = VoidReturnTypeTest.class; + vh = MethodHandles.lookup().findVarHandle(cls, "i", Object.class); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + @Override + protected void doTest() { + vh.set(this, null); + try { + int i = (int) vh.get(this); + failUnreachable(); + } catch (NullPointerException cce) { + } + + vh.set(this, new Object()); + try { + int i = (int) vh.get(this); + failUnreachable(); + } catch (ClassCastException cce) { + } + + vh.set(this, Integer.valueOf(42)); + { + int i = (int) vh.get(this); + } + + vh.set(this, new ReferenceReturnTypeTest()); + try { + int i = (int) vh.get(this); + } catch (ClassCastException cce) { + } + } + + public static void main(String[] args) { + new ReferenceReturnTypeTest().run(); + } + } + // // Tests that a null reference as a boxed primitive type argument // throws a NullPointerException. These vary the VarHandle type |