summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Orion Hodson <oth@google.com> 2022-12-09 17:40:28 +0000
committer Orion Hodson <oth@google.com> 2022-12-12 13:33:39 +0000
commit5a454c6ed6bb692f5881a68ea9177d50e735b101 (patch)
treee1207f5eb3528e939c8e6580dd1524aa5bb93367
parent5d3a23dd7d288b98a0713289072db785d01615c8 (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.cc7
-rw-r--r--runtime/method_handles_test.cc2
-rw-r--r--test/712-varhandle-invocations/src/VarHandleTypeConversionTests.java46
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