VarHandle desugar: Better handling of polymorphic return types
Bug: b/247076137
Change-Id: If14311abf0e2fe40a28f09dd0168a37d8523b6ba
diff --git a/src/test/examplesJava9/varhandle/InstanceIntField.java b/src/test/examplesJava9/varhandle/InstanceIntField.java
index 0320030..aeadbcc 100644
--- a/src/test/examplesJava9/varhandle/InstanceIntField.java
+++ b/src/test/examplesJava9/varhandle/InstanceIntField.java
@@ -18,10 +18,54 @@
throw e;
}
- public static void testSet(VarHandle varHandle) {
+ public static void testGet(VarHandle varHandle) {
System.out.println("testGet");
InstanceIntField instance = new InstanceIntField();
+ varHandle.set(instance, 1);
+
+ System.out.println(varHandle.get(instance));
+ System.out.println((Object) varHandle.get(instance));
+ System.out.println((int) varHandle.get(instance));
+ System.out.println((long) varHandle.get(instance));
+ System.out.println((float) varHandle.get(instance));
+ System.out.println((double) varHandle.get(instance));
+ try {
+ System.out.println((boolean) varHandle.get(instance));
+ System.out.println("Unexpected success");
+ } catch (RuntimeException e) {
+ checkJavaLangInvokeWrongMethodTypeException(e);
+ }
+ try {
+ System.out.println((byte) varHandle.get(instance));
+ System.out.println("Unexpected success");
+ } catch (RuntimeException e) {
+ checkJavaLangInvokeWrongMethodTypeException(e);
+ }
+ try {
+ System.out.println((short) varHandle.get(instance));
+ System.out.println("Unexpected success");
+ } catch (RuntimeException e) {
+ checkJavaLangInvokeWrongMethodTypeException(e);
+ }
+ try {
+ System.out.println((char) varHandle.get(instance));
+ System.out.println("Unexpected success");
+ } catch (RuntimeException e) {
+ checkJavaLangInvokeWrongMethodTypeException(e);
+ }
+ try {
+ System.out.println((String) varHandle.get(instance));
+ System.out.println("Unexpected success");
+ } catch (RuntimeException e) {
+ checkJavaLangInvokeWrongMethodTypeException(e);
+ }
+ }
+
+ public static void testSet(VarHandle varHandle) {
+ System.out.println("testSet");
+
+ InstanceIntField instance = new InstanceIntField();
System.out.println((int) varHandle.get(instance));
// int and Integer values.
@@ -217,6 +261,7 @@
public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
VarHandle varHandle =
MethodHandles.lookup().findVarHandle(InstanceIntField.class, "field", int.class);
+ testGet(varHandle);
testSet(varHandle);
testCompareAndSet(varHandle);
}
diff --git a/src/test/examplesJava9/varhandle/InstanceLongField.java b/src/test/examplesJava9/varhandle/InstanceLongField.java
index fac0ef3..b23e692 100644
--- a/src/test/examplesJava9/varhandle/InstanceLongField.java
+++ b/src/test/examplesJava9/varhandle/InstanceLongField.java
@@ -18,6 +18,55 @@
throw e;
}
+ public static void testGet(VarHandle varHandle) {
+ System.out.println("testGet");
+
+ InstanceLongField instance = new InstanceLongField();
+ varHandle.set(instance, 1L);
+
+ System.out.println(varHandle.get(instance));
+ System.out.println((Object) varHandle.get(instance));
+ System.out.println((long) varHandle.get(instance));
+ System.out.println((float) varHandle.get(instance));
+ System.out.println((double) varHandle.get(instance));
+ try {
+ System.out.println((boolean) varHandle.get(instance));
+ System.out.println("Unexpected success");
+ } catch (RuntimeException e) {
+ checkJavaLangInvokeWrongMethodTypeException(e);
+ }
+ try {
+ System.out.println((byte) varHandle.get(instance));
+ System.out.println("Unexpected success");
+ } catch (RuntimeException e) {
+ checkJavaLangInvokeWrongMethodTypeException(e);
+ }
+ try {
+ System.out.println((short) varHandle.get(instance));
+ System.out.println("Unexpected success");
+ } catch (RuntimeException e) {
+ checkJavaLangInvokeWrongMethodTypeException(e);
+ }
+ try {
+ System.out.println((char) varHandle.get(instance));
+ System.out.println("Unexpected success");
+ } catch (RuntimeException e) {
+ checkJavaLangInvokeWrongMethodTypeException(e);
+ }
+ try {
+ System.out.println((int) varHandle.get(instance));
+ System.out.println("Unexpected success 5");
+ } catch (RuntimeException e) {
+ checkJavaLangInvokeWrongMethodTypeException(e);
+ }
+ try {
+ System.out.println((String) varHandle.get(instance));
+ System.out.println("Unexpected success");
+ } catch (RuntimeException e) {
+ checkJavaLangInvokeWrongMethodTypeException(e);
+ }
+ }
+
public static void testSet(VarHandle varHandle) {
System.out.println("testSet");
@@ -187,6 +236,7 @@
public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
VarHandle varHandle =
MethodHandles.lookup().findVarHandle(InstanceLongField.class, "field", long.class);
+ testGet(varHandle);
testSet(varHandle);
testCompareAndSet(varHandle);
}
diff --git a/src/test/examplesJava9/varhandle/InstanceStringField.java b/src/test/examplesJava9/varhandle/InstanceStringField.java
index 1be6f67..231ee6a 100644
--- a/src/test/examplesJava9/varhandle/InstanceStringField.java
+++ b/src/test/examplesJava9/varhandle/InstanceStringField.java
@@ -14,12 +14,31 @@
System.out.println(s);
}
- public static void testSet(VarHandle varHandle) {
+ public static void testGet(VarHandle varHandle) {
System.out.println("testGet");
InstanceStringField instance = new InstanceStringField();
// Then polymorphic invoke will remove the cast and make that as the return type of the get.
+ System.out.println((String) varHandle.get(instance));
+ varHandle.set(instance, "1");
+ System.out.println(varHandle.get(instance));
+ System.out.println((Object) varHandle.get(instance));
+ System.out.println((String) varHandle.get(instance));
+ System.out.println((CharSequence) varHandle.get(instance));
+ try {
+ System.out.println((Byte) varHandle.get(instance));
+ System.out.println("Unexpected success");
+ } catch (ClassCastException e) {
+ }
+ }
+
+ public static void testSet(VarHandle varHandle) {
+ System.out.println("testSet");
+
+ InstanceStringField instance = new InstanceStringField();
+
+ // Then polymorphic invoke will remove the cast and make that as the return type of the get.
println((String) varHandle.get(instance));
varHandle.set(instance, "1");
println((String) varHandle.get(instance));
@@ -39,6 +58,7 @@
public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
VarHandle varHandle =
MethodHandles.lookup().findVarHandle(InstanceStringField.class, "field", Object.class);
+ testGet(varHandle);
testSet(varHandle);
testCompareAndSet(varHandle);
}
diff --git a/src/test/java/com/android/tools/r8/cf/varhandle/VarHandleDesugaringInstanceIntFieldTest.java b/src/test/java/com/android/tools/r8/cf/varhandle/VarHandleDesugaringInstanceIntFieldTest.java
index 7cfc0e5..f676891 100644
--- a/src/test/java/com/android/tools/r8/cf/varhandle/VarHandleDesugaringInstanceIntFieldTest.java
+++ b/src/test/java/com/android/tools/r8/cf/varhandle/VarHandleDesugaringInstanceIntFieldTest.java
@@ -17,6 +17,13 @@
private static final String EXPECTED_OUTPUT =
StringUtils.lines(
"testGet",
+ "1",
+ "1",
+ "1",
+ "1",
+ "1.0",
+ "1.0",
+ "testSet",
"0",
"1",
"2",
diff --git a/src/test/java/com/android/tools/r8/cf/varhandle/VarHandleDesugaringInstanceLongFieldTest.java b/src/test/java/com/android/tools/r8/cf/varhandle/VarHandleDesugaringInstanceLongFieldTest.java
index 227cc76..7303ec5 100644
--- a/src/test/java/com/android/tools/r8/cf/varhandle/VarHandleDesugaringInstanceLongFieldTest.java
+++ b/src/test/java/com/android/tools/r8/cf/varhandle/VarHandleDesugaringInstanceLongFieldTest.java
@@ -16,6 +16,12 @@
private static final String EXPECTED_OUTPUT =
StringUtils.lines(
+ "testGet",
+ "1",
+ "1",
+ "1",
+ "1.0",
+ "1.0",
"testSet",
"0",
"1",
diff --git a/src/test/java/com/android/tools/r8/cf/varhandle/VarHandleDesugaringInstanceStringFieldTest.java b/src/test/java/com/android/tools/r8/cf/varhandle/VarHandleDesugaringInstanceStringFieldTest.java
index f33f52c..f1440c1 100644
--- a/src/test/java/com/android/tools/r8/cf/varhandle/VarHandleDesugaringInstanceStringFieldTest.java
+++ b/src/test/java/com/android/tools/r8/cf/varhandle/VarHandleDesugaringInstanceStringFieldTest.java
@@ -15,7 +15,19 @@
public class VarHandleDesugaringInstanceStringFieldTest extends VarHandleDesugaringTestBase {
private static final String EXPECTED_OUTPUT =
- StringUtils.lines("testGet", "null", "1", "testCompareAndSet", "null", "1");
+ StringUtils.lines(
+ "testGet",
+ "null",
+ "1",
+ "1",
+ "1",
+ "1",
+ "testSet",
+ "null",
+ "1",
+ "testCompareAndSet",
+ "null",
+ "1");
private static final String MAIN_CLASS = VarHandle.InstanceStringField.typeName();
private static final String JAR_ENTRY = "varhandle/InstanceStringField.class";
@@ -38,4 +50,9 @@
protected String getExpectedOutputForReferenceImplementation() {
return EXPECTED_OUTPUT;
}
+
+ @Override
+ protected boolean getTestWithDesugaring() {
+ return true;
+ }
}
diff --git a/src/test/java/com/android/tools/r8/ir/desugar/varhandle/DesugarVarHandle.java b/src/test/java/com/android/tools/r8/ir/desugar/varhandle/DesugarVarHandle.java
index 5780485..2ba4cf4 100644
--- a/src/test/java/com/android/tools/r8/ir/desugar/varhandle/DesugarVarHandle.java
+++ b/src/test/java/com/android/tools/r8/ir/desugar/varhandle/DesugarVarHandle.java
@@ -142,11 +142,38 @@
return U.getObject(ct1, offset);
}
+ Object getInBox(Object ct1, Class<?> expectedBox) {
+ if (type == int.class) {
+ int value = U.getInt(ct1, offset);
+ if (expectedBox == Long.class) {
+ return Long.valueOf(value);
+ }
+ if (expectedBox == Float.class) {
+ return Float.valueOf(value);
+ }
+ if (expectedBox == Double.class) {
+ return Double.valueOf(value);
+ }
+ throw desugarWrongMethodTypeException();
+ }
+ if (type == long.class) {
+ long value = U.getLong(ct1, offset);
+ if (expectedBox == Float.class) {
+ return Float.valueOf(value);
+ }
+ if (expectedBox == Double.class) {
+ return Double.valueOf(value);
+ }
+ throw desugarWrongMethodTypeException();
+ }
+ return U.getObject(ct1, offset);
+ }
+
int getInt(Object ct1) {
if (type == int.class) {
return U.getInt(ct1, offset);
} else if (type == long.class) {
- return (int) U.getLong(ct1, offset);
+ throw desugarWrongMethodTypeException();
} else {
return toIntIfPossible(U.getObject(ct1, offset), true);
}
diff --git a/src/test/java/com/android/tools/r8/ir/desugar/varhandle/GenerateVarHandleMethods.java b/src/test/java/com/android/tools/r8/ir/desugar/varhandle/GenerateVarHandleMethods.java
index 369bc51..7052773 100644
--- a/src/test/java/com/android/tools/r8/ir/desugar/varhandle/GenerateVarHandleMethods.java
+++ b/src/test/java/com/android/tools/r8/ir/desugar/varhandle/GenerateVarHandleMethods.java
@@ -223,7 +223,8 @@
for (String prefix : ImmutableList.of("get", "set", "compareAndSet")) {
if (name.startsWith(prefix)
&& (name.substring(prefix.length()).equals("Int")
- || name.substring(prefix.length()).equals("Long"))) {
+ || name.substring(prefix.length()).equals("Long")
+ || name.substring(prefix.length()).equals("InBox"))) {
return prefix;
}
}