Reproduce member rebinding bug leading to illegal accesses
Bug: 151480842
Change-Id: I5441b3dee3b235385bac4001b7159ea3414b12c9
diff --git a/src/test/java/com/android/tools/r8/memberrebinding/MemberRebindingConflictTest.java b/src/test/java/com/android/tools/r8/memberrebinding/MemberRebindingConflictTest.java
new file mode 100644
index 0000000..e081a44
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/memberrebinding/MemberRebindingConflictTest.java
@@ -0,0 +1,99 @@
+// Copyright (c) 2020, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.android.tools.r8.memberrebinding;
+
+import static org.hamcrest.core.StringContains.containsString;
+
+import com.android.tools.r8.NeverInline;
+import com.android.tools.r8.NeverMerge;
+import com.android.tools.r8.R8TestRunResult;
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.TestParametersCollection;
+import com.android.tools.r8.graph.MethodAccessFlags;
+import com.android.tools.r8.memberrebinding.testclasses.MemberRebindingConflictTestClasses;
+import com.android.tools.r8.memberrebinding.testclasses.MemberRebindingConflictTestClasses.C;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+@RunWith(Parameterized.class)
+public class MemberRebindingConflictTest extends TestBase {
+
+ private final TestParameters parameters;
+
+ @Parameterized.Parameters(name = "{0}")
+ public static TestParametersCollection data() {
+ return getTestParameters().withAllRuntimesAndApiLevels().build();
+ }
+
+ public MemberRebindingConflictTest(TestParameters parameters) {
+ this.parameters = parameters;
+ }
+
+ @Test
+ public void test() throws Exception {
+ R8TestRunResult result =
+ testForR8(parameters.getBackend())
+ .addProgramClasses(A.class, TestClass.class)
+ .addProgramClassFileData(
+ transformer(B.class)
+ .removeMethods(
+ (access, name, descriptor, signature, exceptions) -> {
+ if (name.equals("foo")) {
+ assert MethodAccessFlags.fromCfAccessFlags(access, false).isSynthetic();
+ return true;
+ }
+ return false;
+ })
+ .transform())
+ .addInnerClasses(MemberRebindingConflictTestClasses.class)
+ .addKeepMainRule(TestClass.class)
+ .enableInliningAnnotations()
+ .enableMergeAnnotations()
+ .enableNeverClassInliningAnnotations()
+ .setMinApi(parameters.getApiLevel())
+ .compile()
+ .run(parameters.getRuntime(), TestClass.class);
+
+ if (parameters.isDexRuntime()
+ && parameters.getRuntime().asDex().getVm().getVersion().isDalvik()) {
+ result.assertSuccessWithOutputLines("foo", "bar", "foo", "baz");
+ } else {
+ result.assertFailureWithErrorThatMatches(
+ containsString(IllegalAccessError.class.getTypeName()));
+ }
+ }
+
+ static class TestClass {
+
+ public static void main(String[] args) {
+ C c = new C();
+ c.bar();
+ c.baz();
+ }
+ }
+
+ @NeverMerge
+ static class A {
+
+ @NeverInline
+ public void foo() {
+ System.out.println("foo");
+ }
+ }
+
+ @NeverMerge
+ public static class B extends A {
+
+ // public synthetic void foo() { super.foo(); }
+
+ @NeverInline
+ public void bar() {
+ foo();
+ System.out.println("bar");
+ }
+ }
+}
diff --git a/src/test/java/com/android/tools/r8/memberrebinding/testclasses/MemberRebindingConflictTestClasses.java b/src/test/java/com/android/tools/r8/memberrebinding/testclasses/MemberRebindingConflictTestClasses.java
new file mode 100644
index 0000000..79f7dd6
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/memberrebinding/testclasses/MemberRebindingConflictTestClasses.java
@@ -0,0 +1,22 @@
+// Copyright (c) 2020, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.android.tools.r8.memberrebinding.testclasses;
+
+import com.android.tools.r8.NeverClassInline;
+import com.android.tools.r8.NeverInline;
+import com.android.tools.r8.memberrebinding.MemberRebindingConflictTest;
+
+public class MemberRebindingConflictTestClasses {
+
+ @NeverClassInline
+ public static class C extends MemberRebindingConflictTest.B {
+
+ @NeverInline
+ public void baz() {
+ super.foo();
+ System.out.println("baz");
+ }
+ }
+}