Reproduce b/123730538: method rebinding missed calling context.
Bug: 111622837, 123730538
Change-Id: Icd9fb10fd781cb28b7ca3627cdbc03fc698e1273
diff --git a/src/test/java/com/android/tools/r8/naming/b123068484/FieldRenamingTest.java b/src/test/java/com/android/tools/r8/naming/b123068484/FieldRenamingTest.java
index 6908fda..4cedaea 100644
--- a/src/test/java/com/android/tools/r8/naming/b123068484/FieldRenamingTest.java
+++ b/src/test/java/com/android/tools/r8/naming/b123068484/FieldRenamingTest.java
@@ -18,8 +18,8 @@
import com.android.tools.r8.utils.codeinspector.FieldSubject;
import com.android.tools.r8.utils.codeinspector.InstructionSubject;
import com.android.tools.r8.utils.codeinspector.MethodSubject;
+import com.google.common.collect.ImmutableList;
import java.nio.file.Path;
-import java.util.LinkedList;
import java.util.List;
import org.junit.BeforeClass;
import org.junit.Test;
@@ -46,9 +46,10 @@
@BeforeClass
public static void setUpClass() throws Exception {
- CLASSES = new LinkedList<>();
- CLASSES.addAll(ToolHelper.getClassFilesForTestPackage(MAIN.getPackage()));
- CLASSES.addAll(ToolHelper.getClassFilesForTestPackage(CONCRETE1.getPackage()));
+ CLASSES = ImmutableList.<Path>builder()
+ .addAll(ToolHelper.getClassFilesForTestPackage(MAIN.getPackage()))
+ .addAll(ToolHelper.getClassFilesForTestPackage(CONCRETE1.getPackage()))
+ .build();
}
@Test
@@ -58,10 +59,9 @@
testForProguard()
.addProgramFiles(inJar)
.addKeepMainRule(MAIN)
- .compile()
- .inspect(this::inspect)
.run(MAIN)
- .assertSuccessWithOutput(EXPECTED_OUTPUT);
+ .assertSuccessWithOutput(EXPECTED_OUTPUT)
+ .inspect(this::inspect);
}
@Test
@@ -69,15 +69,15 @@
testForR8(backend)
.addProgramFiles(CLASSES)
.addKeepMainRule(MAIN)
- .compile()
- .inspect(this::inspect)
.run(MAIN)
- .assertSuccessWithOutput(EXPECTED_OUTPUT);
+ .assertSuccessWithOutput(EXPECTED_OUTPUT)
+ .inspect(this::inspect);
}
private void inspect(CodeInspector inspector) {
FieldSubject fld = inspector.clazz(CONCRETE1.getTypeName().replace("Concrete1", "Abs"))
.uniqueFieldWithName("strField");
+ assertThat(fld, isPresent());
ClassSubject main = inspector.clazz(MAIN);
assertThat(main, isPresent());
diff --git a/src/test/java/com/android/tools/r8/resolution/b123730538/B123730538.java b/src/test/java/com/android/tools/r8/resolution/b123730538/B123730538.java
new file mode 100644
index 0000000..e298c9d
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/resolution/b123730538/B123730538.java
@@ -0,0 +1,99 @@
+// Copyright (c) 2019, 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.resolution.b123730538;
+
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertThat;
+
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.ToolHelper;
+import com.android.tools.r8.resolution.b123730538.runner.PublicClassExtender;
+import com.android.tools.r8.resolution.b123730538.runner.Runner;
+import com.android.tools.r8.resolution.b123730538.sub.PublicClass;
+import com.android.tools.r8.utils.StringUtils;
+import com.android.tools.r8.utils.codeinspector.ClassSubject;
+import com.android.tools.r8.utils.codeinspector.CodeInspector;
+import com.android.tools.r8.utils.codeinspector.InstructionSubject;
+import com.android.tools.r8.utils.codeinspector.MethodSubject;
+import com.google.common.collect.ImmutableList;
+import java.nio.file.Path;
+import java.util.List;
+import org.junit.BeforeClass;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+@RunWith(Parameterized.class)
+public class B123730538 extends TestBase {
+ private static final Class MAIN = Runner.class;
+ private static List<Path> CLASSES;
+ private static final String EXPECTED_OUTPUT = StringUtils.lines("pkg.AbstractClass::foo");
+
+ private final Backend backend;
+
+ @Parameterized.Parameters(name = "Backend: {0}")
+ public static Object[] data() {
+ return Backend.values();
+ }
+
+ public B123730538(Backend backend) {
+ this.backend = backend;
+ }
+
+ @BeforeClass
+ public static void setUpClass() throws Exception {
+ CLASSES = ImmutableList.<Path>builder()
+ .addAll(ToolHelper.getClassFilesForTestPackage(MAIN.getPackage()))
+ .addAll(ToolHelper.getClassFilesForTestPackage(PublicClass.class.getPackage()))
+ .build();
+ }
+
+ @Test
+ public void testProguard() throws Exception {
+ Path inJar = temp.newFile("input.jar").toPath().toAbsolutePath();
+ writeToJar(inJar, CLASSES);
+ testForProguard()
+ .addProgramFiles(inJar)
+ .addKeepMainRule(MAIN)
+ .run(MAIN)
+ .assertSuccessWithOutput(EXPECTED_OUTPUT)
+ .inspect(this::inspect);
+ }
+
+ @Ignore("b/123730538")
+ @Test
+ public void testR8() throws Exception {
+ testForR8(backend)
+ .addProgramFiles(CLASSES)
+ .addKeepMainRule(MAIN)
+ .run(MAIN)
+ .assertSuccessWithOutput(EXPECTED_OUTPUT)
+ .inspect(this::inspect);
+ }
+
+ private void inspect(CodeInspector inspector) {
+ MethodSubject foo = inspector.clazz(
+ PublicClass.class.getTypeName().replace("PublicClass", "AbstractClass"))
+ .uniqueMethodWithName("foo");
+ assertThat(foo, isPresent());
+
+ ClassSubject main = inspector.clazz(PublicClassExtender.class);
+ assertThat(main, isPresent());
+ MethodSubject methodSubject = main.uniqueMethodWithName("delegate");
+ assertThat(methodSubject, isPresent());
+
+ methodSubject
+ .iterateInstructions(InstructionSubject::isInvokeVirtual)
+ .forEachRemaining(instructionSubject -> {
+ String methodName = instructionSubject.getMethod().name.toString();
+ // Method references will be renamed.
+ assertNotEquals("foo", methodName);
+ assertEquals(foo.getFinalName(), methodName);
+ });
+ }
+
+}
diff --git a/src/test/java/com/android/tools/r8/resolution/b123730538/runner/AnotherPublicClassExtender.java b/src/test/java/com/android/tools/r8/resolution/b123730538/runner/AnotherPublicClassExtender.java
new file mode 100644
index 0000000..8377885
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/resolution/b123730538/runner/AnotherPublicClassExtender.java
@@ -0,0 +1,13 @@
+// Copyright (c) 2019, 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.resolution.b123730538.runner;
+
+import com.android.tools.r8.resolution.b123730538.sub.AnotherPublicClass;
+
+// To make AbstractPublicClass not mergeable for both R8 and Proguard.
+class AnotherPublicClassExtender extends AnotherPublicClass {
+ void delegate() {
+ foo();
+ }
+}
diff --git a/src/test/java/com/android/tools/r8/resolution/b123730538/runner/PublicClassExtender.java b/src/test/java/com/android/tools/r8/resolution/b123730538/runner/PublicClassExtender.java
new file mode 100644
index 0000000..b866eea
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/resolution/b123730538/runner/PublicClassExtender.java
@@ -0,0 +1,15 @@
+// Copyright (c) 2019, 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.resolution.b123730538.runner;
+
+import com.android.tools.r8.resolution.b123730538.sub.PublicClass;
+
+public class PublicClassExtender extends PublicClass {
+ void delegate() {
+ // Method reference should be PublicClassExtender#foo, not the definition AbstractClass#foo
+ // because package-private AbstractClass is not visible from this calling context.
+ // Otherwise, we will see java.lang.IllegalAccessError.
+ foo();
+ }
+}
diff --git a/src/test/java/com/android/tools/r8/resolution/b123730538/runner/Runner.java b/src/test/java/com/android/tools/r8/resolution/b123730538/runner/Runner.java
new file mode 100644
index 0000000..54e0c6e
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/resolution/b123730538/runner/Runner.java
@@ -0,0 +1,26 @@
+// Copyright (c) 2019, 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.resolution.b123730538.runner;
+
+public class Runner {
+
+ static int counter = 0;
+
+ static Object create() {
+ if (counter++ % 2 == 0) {
+ return new PublicClassExtender();
+ } else {
+ return new AnotherPublicClassExtender();
+ }
+ }
+
+ public static void main(String[] args) {
+ Object instance = create();
+ if (instance instanceof PublicClassExtender) {
+ ((PublicClassExtender) instance).delegate();
+ } else {
+ ((AnotherPublicClassExtender) instance).delegate();
+ }
+ }
+}
diff --git a/src/test/java/com/android/tools/r8/resolution/b123730538/sub/AbstractClass.java b/src/test/java/com/android/tools/r8/resolution/b123730538/sub/AbstractClass.java
new file mode 100644
index 0000000..a99e9c5
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/resolution/b123730538/sub/AbstractClass.java
@@ -0,0 +1,10 @@
+// Copyright (c) 2019, 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.resolution.b123730538.sub;
+
+abstract class AbstractClass {
+ protected void foo() {
+ System.out.println("pkg.AbstractClass::foo");
+ }
+}
diff --git a/src/test/java/com/android/tools/r8/resolution/b123730538/sub/AnotherPublicClass.java b/src/test/java/com/android/tools/r8/resolution/b123730538/sub/AnotherPublicClass.java
new file mode 100644
index 0000000..b9433a1
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/resolution/b123730538/sub/AnotherPublicClass.java
@@ -0,0 +1,8 @@
+// Copyright (c) 2019, 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.resolution.b123730538.sub;
+
+// To make AbstractClass not mergeable for both R8 and Proguard.
+public class AnotherPublicClass extends AbstractClass {
+}
diff --git a/src/test/java/com/android/tools/r8/resolution/b123730538/sub/PublicClass.java b/src/test/java/com/android/tools/r8/resolution/b123730538/sub/PublicClass.java
new file mode 100644
index 0000000..c3afbfc
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/resolution/b123730538/sub/PublicClass.java
@@ -0,0 +1,7 @@
+// Copyright (c) 2019, 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.resolution.b123730538.sub;
+
+public class PublicClass extends AbstractClass {
+}