Version 2.0.32

Backport fix for classinlining static roots with instance fields. The
diff is part of the CL below which fixes the issue.

CL: https://r8-review.googlesource.com/47320/

Bug: 149781762
Change-Id: I0bd7afef5e70380fff379adc5a53d27ec8b3a6f5
diff --git a/src/main/java/com/android/tools/r8/Version.java b/src/main/java/com/android/tools/r8/Version.java
index d38eb99..7944c37 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.32";
+  public static final String LABEL = "2.0.33";
 
   private Version() {
   }
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/classinliner/InlineCandidateProcessor.java b/src/main/java/com/android/tools/r8/ir/optimize/classinliner/InlineCandidateProcessor.java
index 5683361..f78ba2c 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/classinliner/InlineCandidateProcessor.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/classinliner/InlineCandidateProcessor.java
@@ -306,10 +306,24 @@
           indirectUsers.addAll(alias.uniqueUsers());
           continue;
         }
-        // Field read/write.
-        if (user.isInstanceGet()
-            || (user.isInstancePut()
-                && receivers.addIllegalReceiverAlias(user.asInstancePut().value()))) {
+
+        if (user.isInstanceGet()) {
+          if (root.isStaticGet()) {
+            // We don't have a replacement for this field read.
+            return user; // Not eligible.
+          }
+          DexEncodedField field =
+              appView.appInfo().resolveField(user.asFieldInstruction().getField());
+          if (field == null || field.isStatic()) {
+            return user; // Not eligible.
+          }
+          continue;
+        }
+
+        if (user.isInstancePut()) {
+          if (!receivers.addIllegalReceiverAlias(user.asInstancePut().value())) {
+            return user; // Not eligible.
+          }
           DexEncodedField field =
               appView.appInfo().resolveField(user.asFieldInstruction().getField());
           if (field == null || field.isStatic()) {
diff --git a/src/test/java/com/android/tools/r8/kotlin/sealed/SealedClassTest.java b/src/test/java/com/android/tools/r8/kotlin/sealed/SealedClassTest.java
new file mode 100644
index 0000000..0d809d2
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/kotlin/sealed/SealedClassTest.java
@@ -0,0 +1,78 @@
+// 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.kotlin.sealed;
+
+import static com.android.tools.r8.KotlinCompilerTool.KOTLINC;
+import static com.android.tools.r8.ToolHelper.getFilesInTestFolderRelativeToClass;
+
+import com.android.tools.r8.CompilationFailedException;
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.TestRuntime;
+import com.android.tools.r8.TestRuntime.CfRuntime;
+import com.android.tools.r8.ToolHelper;
+import com.android.tools.r8.ToolHelper.KotlinTargetVersion;
+import java.io.IOException;
+import java.nio.file.Path;
+import java.util.List;
+import java.util.concurrent.ExecutionException;
+import java.util.function.BiFunction;
+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 SealedClassTest extends TestBase {
+
+  private static final String MAIN = "com.android.tools.r8.kotlin.sealed.kt.FormatKt";
+  private static final String[] EXPECTED = new String[] {"ZIP"};
+
+  private final TestParameters parameters;
+  private final KotlinTargetVersion targetVersion;
+
+  @Parameters(name = "{0}")
+  public static List<Object[]> data() {
+    return buildParameters(
+        getTestParameters().withAllRuntimesAndApiLevels().build(), KotlinTargetVersion.values());
+  }
+
+  public SealedClassTest(TestParameters parameters, KotlinTargetVersion targetVersion) {
+    this.parameters = parameters;
+    this.targetVersion = targetVersion;
+  }
+
+  private static BiFunction<TestRuntime, KotlinTargetVersion, Path> compilationResults =
+      memoizeBiFunction(SealedClassTest::compileKotlinCode);
+
+  private static Path compileKotlinCode(TestRuntime runtime, KotlinTargetVersion targetVersion)
+      throws IOException {
+    CfRuntime cfRuntime = runtime.isCf() ? runtime.asCf() : TestRuntime.getCheckedInJdk9();
+    return kotlinc(cfRuntime, getStaticTemp(), KOTLINC, targetVersion)
+        .addSourceFiles(getFilesInTestFolderRelativeToClass(SealedClassTest.class, "kt", ".kt"))
+        .compile();
+  }
+
+  @Test
+  public void testRuntime() throws ExecutionException, CompilationFailedException, IOException {
+    testForRuntime(parameters)
+        .addProgramFiles(compilationResults.apply(parameters.getRuntime(), targetVersion))
+        .addRunClasspathFiles(buildOnDexRuntime(parameters, ToolHelper.getKotlinStdlibJar()))
+        .run(parameters.getRuntime(), MAIN)
+        .assertSuccessWithOutputLines(EXPECTED);
+  }
+
+  @Test
+  public void testR8() throws ExecutionException, CompilationFailedException, IOException {
+    testForR8(parameters.getBackend())
+        .addProgramFiles(compilationResults.apply(parameters.getRuntime(), targetVersion))
+        .addProgramFiles(buildOnDexRuntime(parameters, ToolHelper.getKotlinStdlibJar()))
+        .setMinApi(parameters.getApiLevel())
+        .allowAccessModification()
+        .addKeepMainRule(MAIN)
+        .run(parameters.getRuntime(), MAIN)
+        .assertSuccessWithOutputLines(EXPECTED);
+  }
+}
diff --git a/src/test/java/com/android/tools/r8/kotlin/sealed/kt/Format.kt b/src/test/java/com/android/tools/r8/kotlin/sealed/kt/Format.kt
new file mode 100644
index 0000000..2c1e189
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/kotlin/sealed/kt/Format.kt
@@ -0,0 +1,20 @@
+// 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.kotlin.sealed.kt
+
+public sealed class Format(val name: String) {
+    object Zip : Format("ZIP")
+    object Directory : Format("DIRECTORY")
+}
+
+fun main() {
+  val value = when ("ZIP") {
+      Format.Zip.name -> Format.Zip
+      Format.Directory.name -> Format.Directory
+      else -> throw IllegalArgumentException(
+          "Valid formats: ${Format.Zip.name} or ${Format.Directory.name}.")
+  }
+  println(value.name)
+}
\ No newline at end of file