Version 2.0.82
Process generated lambda accessibility bridges to ensure references to
staticizer candidates are tracked correctly
Bug: 158432019
Change-Id: I09fc263ea81b24bf079a4826a3c01a75bbcb990a
diff --git a/src/main/java/com/android/tools/r8/Version.java b/src/main/java/com/android/tools/r8/Version.java
index 090e266..f583fe5 100644
--- a/src/main/java/com/android/tools/r8/Version.java
+++ b/src/main/java/com/android/tools/r8/Version.java
@@ -11,7 +11,7 @@
// This field is accessed from release scripts using simple pattern matching.
// Therefore, changing this field could break our release scripts.
- public static final String LABEL = "2.0.81";
+ public static final String LABEL = "2.0.82";
private Version() {
}
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/LambdaRewriter.java b/src/main/java/com/android/tools/r8/ir/desugar/LambdaRewriter.java
index 97ebc58..3f5b70c 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/LambdaRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/LambdaRewriter.java
@@ -181,13 +181,13 @@
OptimizationFeedbackDelayed feedback,
LensCodeRewriter lensCodeRewriter)
throws ExecutionException {
- Set<DexEncodedMethod> nonDexAccessibilityBridges = Sets.newIdentityHashSet();
+ Set<DexEncodedMethod> accessibilityBridges = Sets.newIdentityHashSet();
for (LambdaClass lambdaClass : lambdaClasses) {
// This call may cause originalMethodSignatures to be updated.
DexEncodedMethod accessibilityBridge =
lambdaClass.target.ensureAccessibilityIfNeeded(feedback);
- if (accessibilityBridge != null && !accessibilityBridge.getCode().isDexCode()) {
- nonDexAccessibilityBridges.add(accessibilityBridge);
+ if (accessibilityBridge != null) {
+ accessibilityBridges.add(accessibilityBridge);
}
}
if (appView.enableWholeProgramOptimizations()) {
@@ -199,10 +199,10 @@
// Ensure that all lambda classes referenced from accessibility bridges are synthesized
// prior to the IR processing of these accessibility bridges.
synthesizeLambdaClassesForWave(
- nonDexAccessibilityBridges, converter, executorService, feedback, lensCodeRewriter);
+ accessibilityBridges, converter, executorService, feedback, lensCodeRewriter);
}
- if (!nonDexAccessibilityBridges.isEmpty()) {
- converter.processMethodsConcurrently(nonDexAccessibilityBridges, executorService);
+ if (!accessibilityBridges.isEmpty()) {
+ converter.processMethodsConcurrently(accessibilityBridges, executorService);
}
}
diff --git a/src/test/java/com/android/tools/r8/regress/b158432019/StaticizerSyntheticUseTest.java b/src/test/java/com/android/tools/r8/regress/b158432019/StaticizerSyntheticUseTest.java
new file mode 100644
index 0000000..e07f8f1
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/regress/b158432019/StaticizerSyntheticUseTest.java
@@ -0,0 +1,100 @@
+// 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.regress.b158432019;
+
+import com.android.tools.r8.NeverClassInline;
+import com.android.tools.r8.NeverInline;
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.TestParametersCollection;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+@RunWith(Parameterized.class)
+public class StaticizerSyntheticUseTest extends TestBase {
+
+ private final TestParameters parameters;
+
+ @Parameters(name = "{0}")
+ public static TestParametersCollection data() {
+ return getTestParameters().withAllRuntimesAndApiLevels().build();
+ }
+
+ public StaticizerSyntheticUseTest(TestParameters parameters) {
+ this.parameters = parameters;
+ }
+
+ @Test
+ public void testRuntime() throws Exception {
+ testForRuntime(parameters)
+ .addProgramClasses(Singleton.class, Main.class, Sam.class, A.class)
+ .run(parameters.getRuntime(), Main.class)
+ .assertSuccessWithOutputLines("Foo", "Foo", "0");
+ }
+
+ @Test
+ public void testR8() throws Exception {
+ testForR8(parameters.getBackend())
+ .addProgramClasses(Singleton.class, Main.class, Sam.class, A.class)
+ .addKeepClassAndMembersRules(Main.class)
+ .setMinApi(parameters.getApiLevel())
+ .noMinification()
+ .enableInliningAnnotations()
+ .enableNeverClassInliningAnnotations()
+ .run(parameters.getRuntime(), Main.class)
+ .assertSuccessWithOutputLines("Foo", "Foo", "0");
+ }
+
+ @NeverClassInline
+ public static class Singleton {
+
+ public static final Singleton singleton = new Singleton();
+
+ @NeverInline
+ public void foo() {
+ System.out.println("Foo");
+ }
+ }
+
+ public interface Sam<T> {
+ T foo(boolean bar);
+ }
+
+ public static class A {
+
+ private int instanceVar = 0;
+
+ public void caller() {
+ // Ensure that the Singleton.foo method is processed to have the generated lambda being
+ // processed - due to all callees being processed.
+ otherChainFirst();
+ Sam<Integer> f =
+ b -> {
+ if (b && instanceVar == 0) {
+ Singleton.singleton.foo();
+ }
+ return instanceVar;
+ };
+ System.out.println(f.foo(System.nanoTime() > 0));
+ }
+
+ public void otherChainFirst() {
+ otherChainSecond();
+ }
+
+ public void otherChainSecond() {
+ Singleton.singleton.foo();
+ }
+ }
+
+ public static class Main {
+
+ public static void main(String[] args) {
+ new A().caller();
+ }
+ }
+}