Version 2.0.84

Cherry pick: Add test for staticizing error on branch 2.0
CL: https://r8-review.googlesource.com/52020

Process generated lambda accessibility bridges to ensure references to
staticizer candidates are tracked correctly

Bug: 158432019
Change-Id: I6df2f54f57c1bd5ea6ad2ecb603a2eac1654bc66
diff --git a/src/main/java/com/android/tools/r8/Version.java b/src/main/java/com/android/tools/r8/Version.java
index 529d800..492d049 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.83";
+  public static final String LABEL = "2.0.84";
 
   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..245a4af 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,17 @@
       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 && accessibilityBridge.hasCode()) {
+        if (!accessibilityBridge.getCode().isDexCode()) {
+          accessibilityBridges.add(accessibilityBridge);
+        } else if (appView.appInfo().hasLiveness() && !appView.options().debug) {
+          accessibilityBridges.add(accessibilityBridge);
+        }
       }
     }
     if (appView.enableWholeProgramOptimizations()) {
@@ -199,10 +203,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();
+    }
+  }
+}