diff --git a/test/162-method-resolution/expected-stdout.txt b/test/162-method-resolution/expected-stdout.txt index 4f3f443449..c82428fcd1 100644 --- a/test/162-method-resolution/expected-stdout.txt +++ b/test/162-method-resolution/expected-stdout.txt @@ -45,3 +45,6 @@ Caught java.lang.reflect.InvocationTargetException caused by java.lang.IncompatibleClassChangeError Calling Test11User.test(): Test11Base.("Test") +Calling Test12User.test(): +Caught java.lang.reflect.InvocationTargetException + caused by java.lang.IllegalAccessError diff --git a/test/162-method-resolution/jasmin/Test10Base.j b/test/162-method-resolution/jasmin/Test12User.j similarity index 61% rename from test/162-method-resolution/jasmin/Test10Base.j rename to test/162-method-resolution/jasmin/Test12User.j index 628f38d6d5..f040dd3f16 100644 --- a/test/162-method-resolution/jasmin/Test10Base.j +++ b/test/162-method-resolution/jasmin/Test12User.j @@ -1,4 +1,4 @@ -; Copyright (C) 2017 The Android Open Source Project +; Copyright (C) 2022 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. @@ -12,14 +12,15 @@ ; See the License for the specific language governing permissions and ; limitations under the License. -.class public Test10Base -.super java/lang/Object -.implements Test10Interface +.class public Test12User +.super java/lang/Object -.method public ()V - .limit stack 1 - .limit locals 1 - aload_0 - invokespecial java/lang/Object/()V - return +.method public static test()V + .limit stack 2 + .limit locals 0 + new Test12Derived + dup + invokespecial Test12Derived.()V + invokevirtual Test12Derived.foo()V + return .end method diff --git a/test/162-method-resolution/src/Main.java b/test/162-method-resolution/src/Main.java index e0ad6b8933..4b8ee920b7 100644 --- a/test/162-method-resolution/src/Main.java +++ b/test/162-method-resolution/src/Main.java @@ -38,6 +38,7 @@ public static void main(String[] args) { test9(); test10(); test11(); + test12(); // TODO: How to test that interface method resolution returns the unique // maximally-specific non-abstract superinterface method if there is one? @@ -383,17 +384,19 @@ private static void test9() throws Exception { * public interface Test10Interface { } * Tested invokes: * invoke-interface Test10Interface.clone()Ljava/lang/Object; from Test10User in first dex - * TODO b/64274113 This should throw a NSME (JLS 13.4.12) but actually throws an ICCE. - * expected: Throws NoSuchMethodError (JLS 13.4.12) - * actual: Throws IncompatibleClassChangeError + * RI: Throws NoSuchMethodError (JLS 13.4.12?) + * ART: Throws IncompatibleClassChangeError. * * This test is simulating compiling Test10Interface with "public Object clone()" method, along - * with every other class. Then we delete "clone" from Test10Interface only, which under JLS - * 13.4.12 is expected to be binary incompatible and throw a NoSuchMethodError. + * with every other class. Then we delete "clone" from Test10Interface only. As there is a + * method with the same signature declared in `java.lang.Object`, ART throws ICCE. For some + * reason RI throws NSME even though 13.4.12 is not applicable due to the superclass declaring + * a method with the same signature and the applicable section 13.4.7 does not specify what + * exception should be thrown (but ICCE is a reasonable choice). * * Files: * src/Test10Interface.java - defines empty interface - * jasmin/Test10Base.j - implements Test10Interface + * src/Test10Base.java - implements Test10Interface * jasmin/Test10User.j - invokeinterface Test10Interface.clone()Ljava/lang/Object; */ private static void test10() throws Exception { @@ -439,6 +442,33 @@ private static void test11() throws Exception { } } + /* + * Test12 + * ----- + * Tested function: + * public class pkg.Test12Base { + * void foo() { ... } // package-private + * } + * public class Test12Derived extends pkg.Test12Base { } + * Tested invokes: + * invoke-virtual Test12Derived.foo()V; from Test12User in first dex + * expected: throws IllegalAccessError (JLS 13.4.7) + * + * This test is simulating compiling Test12Derived with "public void foo()" method, along + * with every other class. Then we delete "foo" from Test12Derived only. The invoke finds + * an inaccessible method in pkg1.Test12Base and throws IAE. + * + * This is somewhat similar to Test10 but throws IAE instead of ICCE. + * + * Files: + * src/pkg/Test12Base.java - declares package-private foo()V + * src/Test12Derived.java - does not declare foo()V + * jasmin/Test12User.j - invokevirtual Test12Derived.foo()V + */ + private static void test12() throws Exception { + invokeUserTest("Test12User"); + } + private static void invokeUserTest(String userName) throws Exception { System.out.println("Calling " + userName + ".test():"); try { diff --git a/test/162-method-resolution/src/Test10Base.java b/test/162-method-resolution/src/Test10Base.java new file mode 100644 index 0000000000..c150037fd0 --- /dev/null +++ b/test/162-method-resolution/src/Test10Base.java @@ -0,0 +1,17 @@ +/* + * Copyright (C) 2017 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. + */ + +public class Test10Base implements Test10Interface { } diff --git a/test/162-method-resolution/src/Test12Derived.java b/test/162-method-resolution/src/Test12Derived.java new file mode 100644 index 0000000000..1a38d1ef18 --- /dev/null +++ b/test/162-method-resolution/src/Test12Derived.java @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2022 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. + */ + +import pkg.Test12Base; + +public class Test12Derived extends Test12Base { +} diff --git a/test/162-method-resolution/src/pkg/Test12Base.java b/test/162-method-resolution/src/pkg/Test12Base.java new file mode 100644 index 0000000000..99f84aca84 --- /dev/null +++ b/test/162-method-resolution/src/pkg/Test12Base.java @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2022 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. + */ + +package pkg; + +public class Test12Base { + /* package-private */ void foo() { + System.out.println("pkg.Test12Base.foo()"); + } +}