VarHandle tests for interfaces

Bug: 65872996
Test: run-test --host 712
Change-Id: I29190f9e86dd60ff9d8428c8fc08e3f84e99baf0
diff --git a/test/712-varhandle-invocations/expected.txt b/test/712-varhandle-invocations/expected.txt
index af92190..1c437cf 100644
--- a/test/712-varhandle-invocations/expected.txt
+++ b/test/712-varhandle-invocations/expected.txt
@@ -2881,6 +2881,161 @@
 ArrayElementGetAndBitwiseXorWidget...OK
 ArrayElementGetAndBitwiseXorReleaseWidget...OK
 ArrayElementGetAndBitwiseXorAcquireWidget...OK
+FieldGetWidgetInterface...OK
+FieldSetWidgetInterface...OK
+FieldGetVolatileWidgetInterface...OK
+FieldSetVolatileWidgetInterface...OK
+FieldGetAcquireWidgetInterface...OK
+FieldSetReleaseWidgetInterface...OK
+FieldGetOpaqueWidgetInterface...OK
+FieldSetOpaqueWidgetInterface...OK
+FieldCompareAndSetWidgetInterface...OK
+FieldCompareAndExchangeWidgetInterface...OK
+FieldCompareAndExchangeAcquireWidgetInterface...OK
+FieldCompareAndExchangeReleaseWidgetInterface...OK
+FieldWeakCompareAndSetPlainWidgetInterface...OK
+FieldWeakCompareAndSetWidgetInterface...OK
+FieldWeakCompareAndSetAcquireWidgetInterface...OK
+FieldWeakCompareAndSetReleaseWidgetInterface...OK
+FieldGetAndSetWidgetInterface...OK
+FieldGetAndSetAcquireWidgetInterface...OK
+FieldGetAndSetReleaseWidgetInterface...OK
+FieldGetAndAddWidgetInterface...OK
+FieldGetAndAddAcquireWidgetInterface...OK
+FieldGetAndAddReleaseWidgetInterface...OK
+FieldGetAndBitwiseOrWidgetInterface...OK
+FieldGetAndBitwiseOrReleaseWidgetInterface...OK
+FieldGetAndBitwiseOrAcquireWidgetInterface...OK
+FieldGetAndBitwiseAndWidgetInterface...OK
+FieldGetAndBitwiseAndReleaseWidgetInterface...OK
+FieldGetAndBitwiseAndAcquireWidgetInterface...OK
+FieldGetAndBitwiseXorWidgetInterface...OK
+FieldGetAndBitwiseXorReleaseWidgetInterface...OK
+FieldGetAndBitwiseXorAcquireWidgetInterface...OK
+FinalFieldGetWidgetInterface...OK
+FinalFieldSetWidgetInterface...OK
+FinalFieldGetVolatileWidgetInterface...OK
+FinalFieldSetVolatileWidgetInterface...OK
+FinalFieldGetAcquireWidgetInterface...OK
+FinalFieldSetReleaseWidgetInterface...OK
+FinalFieldGetOpaqueWidgetInterface...OK
+FinalFieldSetOpaqueWidgetInterface...OK
+FinalFieldCompareAndSetWidgetInterface...OK
+FinalFieldCompareAndExchangeWidgetInterface...OK
+FinalFieldCompareAndExchangeAcquireWidgetInterface...OK
+FinalFieldCompareAndExchangeReleaseWidgetInterface...OK
+FinalFieldWeakCompareAndSetPlainWidgetInterface...OK
+FinalFieldWeakCompareAndSetWidgetInterface...OK
+FinalFieldWeakCompareAndSetAcquireWidgetInterface...OK
+FinalFieldWeakCompareAndSetReleaseWidgetInterface...OK
+FinalFieldGetAndSetWidgetInterface...OK
+FinalFieldGetAndSetAcquireWidgetInterface...OK
+FinalFieldGetAndSetReleaseWidgetInterface...OK
+FinalFieldGetAndAddWidgetInterface...OK
+FinalFieldGetAndAddAcquireWidgetInterface...OK
+FinalFieldGetAndAddReleaseWidgetInterface...OK
+FinalFieldGetAndBitwiseOrWidgetInterface...OK
+FinalFieldGetAndBitwiseOrReleaseWidgetInterface...OK
+FinalFieldGetAndBitwiseOrAcquireWidgetInterface...OK
+FinalFieldGetAndBitwiseAndWidgetInterface...OK
+FinalFieldGetAndBitwiseAndReleaseWidgetInterface...OK
+FinalFieldGetAndBitwiseAndAcquireWidgetInterface...OK
+FinalFieldGetAndBitwiseXorWidgetInterface...OK
+FinalFieldGetAndBitwiseXorReleaseWidgetInterface...OK
+FinalFieldGetAndBitwiseXorAcquireWidgetInterface...OK
+StaticFieldGetWidgetInterface...OK
+StaticFieldSetWidgetInterface...OK
+StaticFieldGetVolatileWidgetInterface...OK
+StaticFieldSetVolatileWidgetInterface...OK
+StaticFieldGetAcquireWidgetInterface...OK
+StaticFieldSetReleaseWidgetInterface...OK
+StaticFieldGetOpaqueWidgetInterface...OK
+StaticFieldSetOpaqueWidgetInterface...OK
+StaticFieldCompareAndSetWidgetInterface...OK
+StaticFieldCompareAndExchangeWidgetInterface...OK
+StaticFieldCompareAndExchangeAcquireWidgetInterface...OK
+StaticFieldCompareAndExchangeReleaseWidgetInterface...OK
+StaticFieldWeakCompareAndSetPlainWidgetInterface...OK
+StaticFieldWeakCompareAndSetWidgetInterface...OK
+StaticFieldWeakCompareAndSetAcquireWidgetInterface...OK
+StaticFieldWeakCompareAndSetReleaseWidgetInterface...OK
+StaticFieldGetAndSetWidgetInterface...OK
+StaticFieldGetAndSetAcquireWidgetInterface...OK
+StaticFieldGetAndSetReleaseWidgetInterface...OK
+StaticFieldGetAndAddWidgetInterface...OK
+StaticFieldGetAndAddAcquireWidgetInterface...OK
+StaticFieldGetAndAddReleaseWidgetInterface...OK
+StaticFieldGetAndBitwiseOrWidgetInterface...OK
+StaticFieldGetAndBitwiseOrReleaseWidgetInterface...OK
+StaticFieldGetAndBitwiseOrAcquireWidgetInterface...OK
+StaticFieldGetAndBitwiseAndWidgetInterface...OK
+StaticFieldGetAndBitwiseAndReleaseWidgetInterface...OK
+StaticFieldGetAndBitwiseAndAcquireWidgetInterface...OK
+StaticFieldGetAndBitwiseXorWidgetInterface...OK
+StaticFieldGetAndBitwiseXorReleaseWidgetInterface...OK
+StaticFieldGetAndBitwiseXorAcquireWidgetInterface...OK
+StaticFinalFieldGetWidgetInterface...OK
+StaticFinalFieldSetWidgetInterface...OK
+StaticFinalFieldGetVolatileWidgetInterface...OK
+StaticFinalFieldSetVolatileWidgetInterface...OK
+StaticFinalFieldGetAcquireWidgetInterface...OK
+StaticFinalFieldSetReleaseWidgetInterface...OK
+StaticFinalFieldGetOpaqueWidgetInterface...OK
+StaticFinalFieldSetOpaqueWidgetInterface...OK
+StaticFinalFieldCompareAndSetWidgetInterface...OK
+StaticFinalFieldCompareAndExchangeWidgetInterface...OK
+StaticFinalFieldCompareAndExchangeAcquireWidgetInterface...OK
+StaticFinalFieldCompareAndExchangeReleaseWidgetInterface...OK
+StaticFinalFieldWeakCompareAndSetPlainWidgetInterface...OK
+StaticFinalFieldWeakCompareAndSetWidgetInterface...OK
+StaticFinalFieldWeakCompareAndSetAcquireWidgetInterface...OK
+StaticFinalFieldWeakCompareAndSetReleaseWidgetInterface...OK
+StaticFinalFieldGetAndSetWidgetInterface...OK
+StaticFinalFieldGetAndSetAcquireWidgetInterface...OK
+StaticFinalFieldGetAndSetReleaseWidgetInterface...OK
+StaticFinalFieldGetAndAddWidgetInterface...OK
+StaticFinalFieldGetAndAddAcquireWidgetInterface...OK
+StaticFinalFieldGetAndAddReleaseWidgetInterface...OK
+StaticFinalFieldGetAndBitwiseOrWidgetInterface...OK
+StaticFinalFieldGetAndBitwiseOrReleaseWidgetInterface...OK
+StaticFinalFieldGetAndBitwiseOrAcquireWidgetInterface...OK
+StaticFinalFieldGetAndBitwiseAndWidgetInterface...OK
+StaticFinalFieldGetAndBitwiseAndReleaseWidgetInterface...OK
+StaticFinalFieldGetAndBitwiseAndAcquireWidgetInterface...OK
+StaticFinalFieldGetAndBitwiseXorWidgetInterface...OK
+StaticFinalFieldGetAndBitwiseXorReleaseWidgetInterface...OK
+StaticFinalFieldGetAndBitwiseXorAcquireWidgetInterface...OK
+ArrayElementGetWidgetInterface...OK
+ArrayElementSetWidgetInterface...OK
+ArrayElementGetVolatileWidgetInterface...OK
+ArrayElementSetVolatileWidgetInterface...OK
+ArrayElementGetAcquireWidgetInterface...OK
+ArrayElementSetReleaseWidgetInterface...OK
+ArrayElementGetOpaqueWidgetInterface...OK
+ArrayElementSetOpaqueWidgetInterface...OK
+ArrayElementCompareAndSetWidgetInterface...OK
+ArrayElementCompareAndExchangeWidgetInterface...OK
+ArrayElementCompareAndExchangeAcquireWidgetInterface...OK
+ArrayElementCompareAndExchangeReleaseWidgetInterface...OK
+ArrayElementWeakCompareAndSetPlainWidgetInterface...OK
+ArrayElementWeakCompareAndSetWidgetInterface...OK
+ArrayElementWeakCompareAndSetAcquireWidgetInterface...OK
+ArrayElementWeakCompareAndSetReleaseWidgetInterface...OK
+ArrayElementGetAndSetWidgetInterface...OK
+ArrayElementGetAndSetAcquireWidgetInterface...OK
+ArrayElementGetAndSetReleaseWidgetInterface...OK
+ArrayElementGetAndAddWidgetInterface...OK
+ArrayElementGetAndAddAcquireWidgetInterface...OK
+ArrayElementGetAndAddReleaseWidgetInterface...OK
+ArrayElementGetAndBitwiseOrWidgetInterface...OK
+ArrayElementGetAndBitwiseOrReleaseWidgetInterface...OK
+ArrayElementGetAndBitwiseOrAcquireWidgetInterface...OK
+ArrayElementGetAndBitwiseAndWidgetInterface...OK
+ArrayElementGetAndBitwiseAndReleaseWidgetInterface...OK
+ArrayElementGetAndBitwiseAndAcquireWidgetInterface...OK
+ArrayElementGetAndBitwiseXorWidgetInterface...OK
+ArrayElementGetAndBitwiseXorReleaseWidgetInterface...OK
+ArrayElementGetAndBitwiseXorAcquireWidgetInterface...OK
 BoxingReturnGetBoolean...OK
 BoxingSetBoolean...OK
 BoxingReturnGetVolatileBoolean...OK
@@ -3179,5 +3334,6 @@
 WideningDoubleReturnValueTest...OK
 SubtypeTest...OK
 SupertypeTest...OK
+InterfaceTest...OK
 ImplicitBoxingIntegerTest...OK
-3182 successes, 0 skips, 0 failures.
+3338 successes, 0 skips, 0 failures.
diff --git a/test/712-varhandle-invocations/src/VarHandleTypeConversionTests.java b/test/712-varhandle-invocations/src/VarHandleTypeConversionTests.java
index c0fbd49..6c02952 100644
--- a/test/712-varhandle-invocations/src/VarHandleTypeConversionTests.java
+++ b/test/712-varhandle-invocations/src/VarHandleTypeConversionTests.java
@@ -1246,6 +1246,105 @@
         }
     }
 
+    public static class InterfaceTest extends VarHandleUnitTest {
+        public interface ParentInterface {
+            int getValue();
+        }
+
+        public interface ChildInterface extends ParentInterface {
+            void setValue(int newValue);
+        }
+
+        public class A implements ParentInterface {
+            protected int value = 0;
+            public int getValue() { return value; }
+        }
+
+        public class B extends A implements ChildInterface {
+            public void setValue(int newValue) { value = newValue; }
+        }
+
+        private ParentInterface pi;
+        private A obj;
+
+        private VarHandle vh_pi;
+        private VarHandle vh_obj;
+        {
+            try {
+                vh_pi = MethodHandles.lookup().findVarHandle(InterfaceTest.class, "pi",
+                                                             InterfaceTest.ParentInterface.class);
+                vh_obj = MethodHandles.lookup().findVarHandle(InterfaceTest.class, "obj",
+                                                              InterfaceTest.A.class);
+            } catch (Exception e) {
+                throw new RuntimeException(e);
+            }
+        }
+
+        public static void main(String[] args) {
+            new InterfaceTest().run();
+        }
+
+        @Override
+        public void doTest() {
+            // Tests using VarHandle to field of type ParentInterface.
+            {
+                pi = (ParentInterface) new A();
+                ParentInterface p = (ParentInterface) vh_pi.get(this);
+                Object o = (Object) vh_pi.get(this);
+                try {
+                    ChildInterface c = (ChildInterface) vh_pi.get(this);
+                    failUnreachable();
+                } catch (ClassCastException expected) {}
+            }
+            {
+                pi = new B();
+                ParentInterface p = (ParentInterface) vh_pi.get(this);
+                B b = (B) vh_pi.get(this);
+                Object o = (Object) vh_pi.get(this);
+                ChildInterface c = (ChildInterface) vh_pi.get(this);
+            }
+            {
+                pi = null;
+                ParentInterface p = (ParentInterface) vh_pi.get(this);
+                B b = (B) vh_pi.get(this);
+                Object o = (Object) vh_pi.get(this);
+                ChildInterface c = (ChildInterface) vh_pi.get(this);
+            }
+
+            // Tests using VarHandle to field of type A.
+            {
+                obj = new A();
+                ParentInterface p = (ParentInterface) vh_obj.get(this);
+                Object o = (Object) vh_obj.get(this);
+                A a = (A) vh_obj.get(this);
+                try {
+                    B b = (B) vh_obj.get(this);
+                    failUnreachable();
+                } catch (ClassCastException e) {}
+                try {
+                    ChildInterface c = (ChildInterface) vh_obj.get(this);
+                    failUnreachable();
+                } catch (ClassCastException e) {}
+            }
+            {
+                obj = new B();
+                ParentInterface p = (ParentInterface) vh_obj.get(this);
+                Object o = (Object) vh_obj.get(this);
+                A a = (A) vh_obj.get(this);
+                B b = (B) vh_obj.get(this);
+                ChildInterface c = (ChildInterface) vh_obj.get(this);
+            }
+            {
+                obj = null;
+                ParentInterface p = (ParentInterface) vh_obj.get(this);
+                Object o = (Object) vh_obj.get(this);
+                A a = (A) vh_obj.get(this);
+                B b = (B) vh_obj.get(this);
+                ChildInterface c = (ChildInterface) vh_obj.get(this);
+            }
+        }
+    }
+
     public static class ImplicitBoxingIntegerTest extends VarHandleUnitTest {
         private static Integer field;
         private static final VarHandle vh;
@@ -1337,6 +1436,7 @@
 
         SubtypeTest.main(args);
         SupertypeTest.main(args);
+        InterfaceTest.main(args);
 
         ImplicitBoxingIntegerTest.main(args);
     }
diff --git a/test/712-varhandle-invocations/src/Widget.java b/test/712-varhandle-invocations/src/Widget.java
index 0282ff8..332b4ea 100644
--- a/test/712-varhandle-invocations/src/Widget.java
+++ b/test/712-varhandle-invocations/src/Widget.java
@@ -15,7 +15,7 @@
  */
 
 // Widget class for reference type accessor tests.
-public class Widget {
+public class Widget implements WidgetInterface {
     protected int requisitionNumber;
 
     public Widget(int requisitionNumber) {
@@ -34,6 +34,8 @@
         return requisitionNumber == wo.requisitionNumber;
     }
 
+    public int getRequisitionNumber() { return requisitionNumber; }
+
     public static final Widget ONE = new Widget(1);
     public static final Widget TWO = new Widget(2);
 }
diff --git a/test/712-varhandle-invocations/src/WidgetInterface.java b/test/712-varhandle-invocations/src/WidgetInterface.java
new file mode 100644
index 0000000..441abbe
--- /dev/null
+++ b/test/712-varhandle-invocations/src/WidgetInterface.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Widget interface for reference type accessor tests.
+public interface WidgetInterface {
+    int getRequisitionNumber();
+}
diff --git a/test/712-varhandle-invocations/util-src/generate_java.py b/test/712-varhandle-invocations/util-src/generate_java.py
index f535b40..f9927db 100644
--- a/test/712-varhandle-invocations/util-src/generate_java.py
+++ b/test/712-varhandle-invocations/util-src/generate_java.py
@@ -722,6 +722,16 @@
         for accessor in VAR_HANDLE_ACCESSORS:
             emit_accessor_test(var_handle_kind, accessor, ref_type, output_path)
 
+def emit_interface_accessor_tests(output_path):
+    ref_type = JavaType("WidgetInterface", [ "Widget.ONE", "Widget.TWO", "null" ])
+    for var_handle_kind in ALL_VAR_HANDLE_KINDS:
+        if var_handle_kind.is_view():
+            # Views as reference type arrays are not supported. They
+            # fail instantiation. This is tested in 710-varhandle-creation.
+            continue
+        for accessor in VAR_HANDLE_ACCESSORS:
+            emit_accessor_test(var_handle_kind, accessor, ref_type, output_path)
+
 def emit_boxing_value_type_accessor_test(accessor, var_type, output_path):
     test_class = "Boxing" + capitalize_first(accessor.method_name) + capitalize_first(var_type.name)
     GENERATED_TEST_CLASSES.append(test_class)
@@ -873,6 +883,7 @@
         sys.exit(1)
     emit_value_type_accessor_tests(final_java_dir)
     emit_reference_accessor_tests(final_java_dir)
+    emit_interface_accessor_tests(final_java_dir)
     emit_boxing_value_type_accessor_tests(final_java_dir)
     emit_main(final_java_dir, argv[2:])