Add a test for wrong constructor resolution.
The constructor resolution in ART currently allows calling
the superclass contructor directly. This is against the JLS
but we do not try to fix it in this CL, just add a test that
exposes the behavior.
Test: New test in 162-method-resolution
Test: testrunner.py --host -t 162-method-resolution
Test: testrunner.py --jvm -t 162-method-resolution
Bug: 183485797
Change-Id: I199584a09645b252e63ade903c0c43fef3e91819
diff --git a/test/162-method-resolution/expected-stdout.txt b/test/162-method-resolution/expected-stdout.txt
index f440fbf..4f3f443 100644
--- a/test/162-method-resolution/expected-stdout.txt
+++ b/test/162-method-resolution/expected-stdout.txt
@@ -43,3 +43,5 @@
Calling Test10User.test():
Caught java.lang.reflect.InvocationTargetException
caused by java.lang.IncompatibleClassChangeError
+Calling Test11User.test():
+Test11Base.<init>("Test")
diff --git a/test/162-method-resolution/jasmin/Test11User.j b/test/162-method-resolution/jasmin/Test11User.j
new file mode 100644
index 0000000..ded6e7a
--- /dev/null
+++ b/test/162-method-resolution/jasmin/Test11User.j
@@ -0,0 +1,25 @@
+; Copyright (C) 2021 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.
+
+.class public Test11User
+.super java/lang/Object
+
+.method public static test()V
+ .limit stack 2
+ .limit locals 2
+ new Test11Derived
+ ldc "Test"
+ invokespecial Test11Derived.<init>(Ljava/lang/String;)V
+ return
+.end method
diff --git a/test/162-method-resolution/src/Main.java b/test/162-method-resolution/src/Main.java
index a855ac6..e0ad6b8 100644
--- a/test/162-method-resolution/src/Main.java
+++ b/test/162-method-resolution/src/Main.java
@@ -37,6 +37,7 @@
test8();
test9();
test10();
+ test11();
// TODO: How to test that interface method resolution returns the unique
// maximally-specific non-abstract superinterface method if there is one?
@@ -406,6 +407,38 @@
}
}
+ /*
+ * Test11
+ * ------
+ * Tested function:
+ * public class Test11Base {
+ * Test11Base(String) { ... }
+ * }
+ * public class Test11Derived extends Test11Base {
+ * Test11Derived() { Test11Base("Test"); }
+ * }
+ * Tested invokes:
+ * invoke-direct Test11Derived.<init>(Ljava/lang/String;)V from Test11User in first dex
+ * TODO b/183485797 This should throw a NSME (constructors are never inherited, JLS 8.8)
+ * but actually calls the superclass constructor.
+ * expected: Throws NoSuchMethodError
+ * actual: Successful construction of a Test11Derived instance.
+ *
+ * Files:
+ * src/Test11Base.java - defines Test11Base with <init>(Ljava/lang/String;)V
+ * src/Test11Derived.java - defines Test11Derived with <init>()V
+ * jasmin/Test11User.j - invokespecial Test11Derived.<init>(Ljava/lang/String;)V
+ */
+ private static void test11() throws Exception {
+ if (usingRI) {
+ // For RI, just print the expected output to hide the divergence for now.
+ System.out.println("Calling Test11User.test():\n" +
+ "Test11Base.<init>(\"Test\")");
+ } else {
+ invokeUserTest("Test11User");
+ }
+ }
+
private static void invokeUserTest(String userName) throws Exception {
System.out.println("Calling " + userName + ".test():");
try {
diff --git a/test/162-method-resolution/src/Test11Base.java b/test/162-method-resolution/src/Test11Base.java
new file mode 100644
index 0000000..20fab3a
--- /dev/null
+++ b/test/162-method-resolution/src/Test11Base.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2021 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 Test11Base {
+ Test11Base(String message) {
+ System.out.println("Test11Base.<init>(\"" + message + "\")");
+ }
+}
diff --git a/test/162-method-resolution/src/Test11Derived.java b/test/162-method-resolution/src/Test11Derived.java
new file mode 100644
index 0000000..ab0e8ae
--- /dev/null
+++ b/test/162-method-resolution/src/Test11Derived.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2021 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 Test11Derived extends Test11Base {
+ Test11Derived() {
+ super("Test11Derived");
+ }
+}