Merge commit '0038458ccfe18b9c1e3008f6b161258949f39d0b' into dev-release
diff --git a/build.gradle b/build.gradle
index 5d4868a..b2e669c 100644
--- a/build.gradle
+++ b/build.gradle
@@ -31,7 +31,7 @@
 
 ext {
     androidSupportVersion = '25.4.0'
-    asmVersion = '9.2'  // When updating update tools/asmifier.py and Toolhelper as well.
+    asmVersion = '9.3'  // When updating update tools/asmifier.py and Toolhelper as well.
     espressoVersion = '3.0.0'
     fastutilVersion = '7.2.0'
     guavaVersion = '30.1.1-jre'
diff --git a/src/library_desugar/desugar_jdk_libs.json b/src/library_desugar/desugar_jdk_libs.json
index 700ea72..59ffcc0 100644
--- a/src/library_desugar/desugar_jdk_libs.json
+++ b/src/library_desugar/desugar_jdk_libs.json
@@ -2,7 +2,7 @@
   "configuration_format_version": 3,
   "group_id" : "com.tools.android",
   "artifact_id" : "desugar_jdk_libs",
-  "version": "1.1.5",
+  "version": "1.1.6",
   "required_compilation_api_level": 26,
   "synthesized_library_classes_package_prefix": "j$.",
   "support_all_callbacks_from_library": true,
@@ -234,9 +234,10 @@
     }
   ],
   "shrinker_config": [
+    "-keepclassmembers class j$.** extends java.io.Serializable { void <init>(); static final long serialVersionUID; java.lang.Object readResolve(); java.lang.Object writeReplace(); private void readObject(java.io.ObjectInputStream); private void writeObject(java.io.ObjectOutputStream); private void readObjectNoData(); }",
     "-keepclassmembers class j$.util.concurrent.ConcurrentHashMap$TreeBin { int lockState; }",
     "-keepclassmembers class j$.util.concurrent.ConcurrentHashMap { int sizeCtl; int transferIndex; long baseCount; int cellsBusy; }",
-    "-keepclassmembers class j$.util.concurrent.ConcurrentHashMap { private void readObject(java.io.ObjectInputStream); private void writeObject(java.io.ObjectOutputStream); private void readObjectNoData(); private static final java.io.ObjectStreamField[] serialPersistentFields; private static final long serialVersionUID;}",
+    "-keepclassmembers class j$.util.concurrent.ConcurrentHashMap { private static final java.io.ObjectStreamField[] serialPersistentFields; }",
     "-keepclassmembers class j$.util.concurrent.ConcurrentHashMap$CounterCell { long value; }",
     "-keepclassmembers enum * { public static **[] values(); public static ** valueOf(java.lang.String); public static final !synthetic <fields>; }",
     "-keeppackagenames j$.**",
diff --git a/src/library_desugar/jdk11/chm_only_desugar_jdk_libs.json b/src/library_desugar/jdk11/chm_only_desugar_jdk_libs.json
index 5f43015..b1ebcd8 100644
--- a/src/library_desugar/jdk11/chm_only_desugar_jdk_libs.json
+++ b/src/library_desugar/jdk11/chm_only_desugar_jdk_libs.json
@@ -1,5 +1,5 @@
 {
-  "identifier": "com.tools.android:chm_only_desugar_jdk_libs:1.0.12",
+  "identifier": "com.tools.android:chm_only_desugar_jdk_libs:1.0.13",
   "configuration_format_version": 100,
   "required_compilation_api_level": 26,
   "synthesized_library_classes_package_prefix": "j$.",
@@ -24,6 +24,7 @@
     }
   ],
   "shrinker_config": [
+    "-keepclassmembers class j$.** extends java.io.Serializable { void <init>(); private static final java.io.ObjectStreamField[] serialPersistentFields; static final long serialVersionUID; java.lang.Object readResolve(); java.lang.Object writeReplace(); private void readObject(java.io.ObjectInputStream); private void writeObject(java.io.ObjectOutputStream); private void readObjectNoData(); }",
     "-keepclassmembers class j$.util.concurrent.ConcurrentHashMap$TreeBin { int lockState; }",
     "-keepclassmembers class j$.util.concurrent.ConcurrentHashMap { int sizeCtl; int transferIndex; long baseCount; int cellsBusy; }",
     "-keepclassmembers class j$.util.concurrent.ConcurrentHashMap$CounterCell { long value; }",
diff --git a/src/library_desugar/jdk11/desugar_jdk_libs.json b/src/library_desugar/jdk11/desugar_jdk_libs.json
index c764f31..45d529c 100644
--- a/src/library_desugar/jdk11/desugar_jdk_libs.json
+++ b/src/library_desugar/jdk11/desugar_jdk_libs.json
@@ -233,9 +233,9 @@
     }
   ],
   "shrinker_config": [
+    "-keepclassmembers class j$.** extends java.io.Serializable { void <init>(); private static final java.io.ObjectStreamField[] serialPersistentFields; static final long serialVersionUID; java.lang.Object readResolve(); java.lang.Object writeReplace(); private void readObject(java.io.ObjectInputStream); private void writeObject(java.io.ObjectOutputStream); private void readObjectNoData(); }",
     "-keepclassmembers class j$.util.concurrent.ConcurrentHashMap$TreeBin { int lockState; }",
     "-keepclassmembers class j$.util.concurrent.ConcurrentHashMap { int sizeCtl; int transferIndex; long baseCount; int cellsBusy; }",
-    "-keepclassmembers class j$.util.concurrent.ConcurrentHashMap { private void readObject(java.io.ObjectInputStream); private void writeObject(java.io.ObjectOutputStream); private void readObjectNoData(); private static final java.io.ObjectStreamField[] serialPersistentFields; private static final long serialVersionUID;}",
     "-keepclassmembers class j$.util.concurrent.ConcurrentHashMap$CounterCell { long value; }",
     "-keepclassmembers enum * { public static **[] values(); public static ** valueOf(java.lang.String); public static final !synthetic <fields>; }",
     "-keeppackagenames java.**",
diff --git a/src/library_desugar/jdk11/desugar_jdk_libs_legacy.json b/src/library_desugar/jdk11/desugar_jdk_libs_legacy.json
index b92af9f..222feda 100644
--- a/src/library_desugar/jdk11/desugar_jdk_libs_legacy.json
+++ b/src/library_desugar/jdk11/desugar_jdk_libs_legacy.json
@@ -211,9 +211,9 @@
     }
   ],
   "shrinker_config": [
+    "-keepclassmembers class j$.** extends java.io.Serializable { void <init>(); private static final java.io.ObjectStreamField[] serialPersistentFields; static final long serialVersionUID; java.lang.Object readResolve(); java.lang.Object writeReplace(); private void readObject(java.io.ObjectInputStream); private void writeObject(java.io.ObjectOutputStream); private void readObjectNoData(); }",
     "-keepclassmembers class j$.util.concurrent.ConcurrentHashMap$TreeBin { int lockState; }",
     "-keepclassmembers class j$.util.concurrent.ConcurrentHashMap { int sizeCtl; int transferIndex; long baseCount; int cellsBusy; }",
-    "-keepclassmembers class j$.util.concurrent.ConcurrentHashMap { private void readObject(java.io.ObjectInputStream); private void writeObject(java.io.ObjectOutputStream); private void readObjectNoData(); private static final java.io.ObjectStreamField[] serialPersistentFields; private static final long serialVersionUID;}",
     "-keepclassmembers class j$.util.concurrent.ConcurrentHashMap$CounterCell { long value; }",
     "-keepclassmembers enum * { public static **[] values(); public static ** valueOf(java.lang.String); public static final !synthetic <fields>; }",
     "-keeppackagenames j$.**",
diff --git a/src/library_desugar/jdk11/desugar_jdk_libs_path.json b/src/library_desugar/jdk11/desugar_jdk_libs_path.json
index c09fa82..7b767e1 100644
--- a/src/library_desugar/jdk11/desugar_jdk_libs_path.json
+++ b/src/library_desugar/jdk11/desugar_jdk_libs_path.json
@@ -452,9 +452,9 @@
     }
   ],
   "shrinker_config": [
+    "-keepclassmembers class j$.** extends java.io.Serializable { void <init>(); private static final java.io.ObjectStreamField[] serialPersistentFields; static final long serialVersionUID; java.lang.Object readResolve(); java.lang.Object writeReplace(); private void readObject(java.io.ObjectInputStream); private void writeObject(java.io.ObjectOutputStream); private void readObjectNoData(); }",
     "-keepclassmembers class j$.util.concurrent.ConcurrentHashMap$TreeBin { int lockState; }",
     "-keepclassmembers class j$.util.concurrent.ConcurrentHashMap { int sizeCtl; int transferIndex; long baseCount; int cellsBusy; }",
-    "-keepclassmembers class j$.util.concurrent.ConcurrentHashMap { private void readObject(java.io.ObjectInputStream); private void writeObject(java.io.ObjectOutputStream); private void readObjectNoData(); private static final java.io.ObjectStreamField[] serialPersistentFields; private static final long serialVersionUID;}",
     "-keepclassmembers class j$.util.concurrent.ConcurrentHashMap$CounterCell { long value; }",
     "-keepclassmembers enum * { public static **[] values(); public static ** valueOf(java.lang.String); public static final !synthetic <fields>; }",
     "-keeppackagenames java.**",
diff --git a/src/library_desugar/jdk11/desugar_jdk_libs_path_alternative_3.json b/src/library_desugar/jdk11/desugar_jdk_libs_path_alternative_3.json
index 5064ba5..a784fd1 100644
--- a/src/library_desugar/jdk11/desugar_jdk_libs_path_alternative_3.json
+++ b/src/library_desugar/jdk11/desugar_jdk_libs_path_alternative_3.json
@@ -318,9 +318,9 @@
     }
   ],
   "shrinker_config": [
+    "-keepclassmembers class j$.** extends java.io.Serializable { void <init>(); private static final java.io.ObjectStreamField[] serialPersistentFields; static final long serialVersionUID; java.lang.Object readResolve(); java.lang.Object writeReplace(); private void readObject(java.io.ObjectInputStream); private void writeObject(java.io.ObjectOutputStream); private void readObjectNoData(); }",
     "-keepclassmembers class j$.util.concurrent.ConcurrentHashMap$TreeBin { int lockState; }",
     "-keepclassmembers class j$.util.concurrent.ConcurrentHashMap { int sizeCtl; int transferIndex; long baseCount; int cellsBusy; }",
-    "-keepclassmembers class j$.util.concurrent.ConcurrentHashMap { private void readObject(java.io.ObjectInputStream); private void writeObject(java.io.ObjectOutputStream); private void readObjectNoData(); private static final java.io.ObjectStreamField[] serialPersistentFields; private static final long serialVersionUID;}",
     "-keepclassmembers class j$.util.concurrent.ConcurrentHashMap$CounterCell { long value; }",
     "-keepclassmembers enum * { public static **[] values(); public static ** valueOf(java.lang.String); public static final !synthetic <fields>; }",
     "-keeppackagenames j$.**",
diff --git a/src/main/java/com/android/tools/r8/R8.java b/src/main/java/com/android/tools/r8/R8.java
index 2145f96..223fc66 100644
--- a/src/main/java/com/android/tools/r8/R8.java
+++ b/src/main/java/com/android/tools/r8/R8.java
@@ -774,6 +774,13 @@
         timing.end();
       }
 
+      if (!options.isMinifying()
+          && appView.options().testing.enableRecordModeling
+          && appView.appInfo().app().getFlags().hasReadRecordReferenceFromProgramClass()) {
+        new Minifier(appView.withLiveness())
+            .replaceDexItemBasedConstString(executorService, timing);
+      }
+
       assert verifyMovedMethodsHaveOriginalMethodPosition(appView, getDirectApp(appView));
 
       // If a method filter is present don't produce output since the application is likely partial.
diff --git a/src/main/java/com/android/tools/r8/cf/CfVersion.java b/src/main/java/com/android/tools/r8/cf/CfVersion.java
index 9ce8c64..df6ee75 100644
--- a/src/main/java/com/android/tools/r8/cf/CfVersion.java
+++ b/src/main/java/com/android/tools/r8/cf/CfVersion.java
@@ -40,6 +40,8 @@
   public static final CfVersion V17_PREVIEW = new CfVersion(Opcodes.V17 | Opcodes.V_PREVIEW);
   public static final CfVersion V18 = new CfVersion(Opcodes.V18);
   public static final CfVersion V18_PREVIEW = new CfVersion(Opcodes.V18 | Opcodes.V_PREVIEW);
+  public static final CfVersion V19 = new CfVersion(Opcodes.V19);
+  public static final CfVersion V19_PREVIEW = new CfVersion(Opcodes.V19 | Opcodes.V_PREVIEW);
 
   private final int version;
 
@@ -61,7 +63,8 @@
     CfVersion.V15,
     CfVersion.V16,
     CfVersion.V17,
-    CfVersion.V18
+    CfVersion.V18,
+    CfVersion.V19
   };
 
   // Private constructor in case we want to canonicalize versions.
@@ -93,6 +96,10 @@
     spec.withInt(CfVersion::major).withInt(CfVersion::minor);
   }
 
+  public static Iterable<CfVersion> all() {
+    return rangeInclusive(versions[0], versions[versions.length - 1]);
+  }
+
   public static Iterable<CfVersion> rangeInclusive(CfVersion from, CfVersion to) {
     assert from.isLessThanOrEqualTo(to);
     assert !from.isPreview() : "This method does not handle preview versions";
diff --git a/src/main/java/com/android/tools/r8/graph/JarClassFileReader.java b/src/main/java/com/android/tools/r8/graph/JarClassFileReader.java
index f669406..8b8b9d8 100644
--- a/src/main/java/com/android/tools/r8/graph/JarClassFileReader.java
+++ b/src/main/java/com/android/tools/r8/graph/JarClassFileReader.java
@@ -530,9 +530,6 @@
     }
 
     private void checkRecord() {
-      if (!application.options.shouldDesugarRecords()) {
-        return;
-      }
       if (!accessFlags.isRecord()) {
         return;
       }
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/enums/EnumUnboxerImpl.java b/src/main/java/com/android/tools/r8/ir/optimize/enums/EnumUnboxerImpl.java
index b2d2531..4867829 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/enums/EnumUnboxerImpl.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/enums/EnumUnboxerImpl.java
@@ -378,7 +378,7 @@
   private void analyzeFieldInstruction(
       FieldInstruction fieldInstruction, Set<DexType> eligibleEnums, ProgramMethod context) {
     DexField field = fieldInstruction.getField();
-    DexProgramClass enumClass = getEnumUnboxingCandidateOrNull(field.holder);
+    DexProgramClass enumClass = getEnumUnboxingCandidateOrNull(field.getHolderType());
     if (enumClass != null) {
       FieldResolutionResult resolutionResult = appView.appInfo().resolveField(field, context);
       if (resolutionResult.isSingleFieldResolutionResult()) {
@@ -552,14 +552,15 @@
           }
         }
       } else if (use.isFieldPut()) {
-        DexType type = use.asFieldInstruction().getField().type;
-        if (enumUnboxingCandidatesInfo.isCandidate(type)) {
-          eligibleEnums.add(type);
+        DexProgramClass enumClass =
+            getEnumUnboxingCandidateOrNull(use.asFieldInstruction().getField().getType());
+        if (enumClass != null) {
+          eligibleEnums.add(enumClass.getType());
         }
       } else if (use.isReturn()) {
-        DexType returnType = code.method().getReference().proto.returnType;
-        if (enumUnboxingCandidatesInfo.isCandidate(returnType)) {
-          eligibleEnums.add(returnType);
+        DexProgramClass enumClass = getEnumUnboxingCandidateOrNull(code.context().getReturnType());
+        if (enumClass != null) {
+          eligibleEnums.add(enumClass.getType());
         }
       }
     }
diff --git a/src/main/java/com/android/tools/r8/naming/IdentifierMinifier.java b/src/main/java/com/android/tools/r8/naming/IdentifierMinifier.java
index ada07f6..0da73cf 100644
--- a/src/main/java/com/android/tools/r8/naming/IdentifierMinifier.java
+++ b/src/main/java/com/android/tools/r8/naming/IdentifierMinifier.java
@@ -132,8 +132,7 @@
         : appView.dexItemFactory().createString(descriptorToJavaType(rewrittenString.toString()));
   }
 
-  private void replaceDexItemBasedConstString(ExecutorService executorService)
-      throws ExecutionException {
+  void replaceDexItemBasedConstString(ExecutorService executorService) throws ExecutionException {
     ThreadUtils.processItems(
         appView.appInfo().classes(),
         clazz -> {
diff --git a/src/main/java/com/android/tools/r8/naming/Minifier.java b/src/main/java/com/android/tools/r8/naming/Minifier.java
index 2177ea3..ef6142f 100644
--- a/src/main/java/com/android/tools/r8/naming/Minifier.java
+++ b/src/main/java/com/android/tools/r8/naming/Minifier.java
@@ -91,6 +91,14 @@
     return lens;
   }
 
+  public void replaceDexItemBasedConstString(ExecutorService executorService, Timing timing)
+      throws ExecutionException {
+    timing.begin("ReplaceDexItemBasedConstString");
+    new IdentifierMinifier(appView, NamingLens.getIdentityLens())
+        .replaceDexItemBasedConstString(executorService);
+    timing.end();
+  }
+
   private List<DexClass> computeReachableInterfacesWithDeterministicOrder(
       SubtypingInfo subtypingInfo) {
     List<DexClass> interfaces = new ArrayList<>();
diff --git a/src/main/java/com/android/tools/r8/retrace/StringRetrace.java b/src/main/java/com/android/tools/r8/retrace/StringRetrace.java
index 1c1a2ee..09f30ca 100644
--- a/src/main/java/com/android/tools/r8/retrace/StringRetrace.java
+++ b/src/main/java/com/android/tools/r8/retrace/StringRetrace.java
@@ -18,6 +18,7 @@
 import java.util.List;
 import java.util.Set;
 import java.util.function.Consumer;
+import java.util.function.Supplier;
 
 /**
  * Specialized Retrace class for retracing string retraces, with special handling for appending
@@ -169,6 +170,22 @@
     return ResultWithContextImpl.create(result, listResultWithContext.getContext());
   }
 
+  /**
+   * Processes supplied strings and calls lineConsumer with retraced strings in a streaming way
+   *
+   * @param lineSupplier the supplier of strings with returning null as terminator
+   * @param lineConsumer the consumer of retraced strings
+   */
+  public void retrace(Supplier<String> lineSupplier, Consumer<String> lineConsumer) {
+    RetraceStackTraceContext context = RetraceStackTraceContext.empty();
+    String retraceLine;
+    while ((retraceLine = lineSupplier.get()) != null) {
+      ResultWithContext<List<String>> result = retrace(retraceLine, context);
+      context = result.getContext();
+      result.getResult().forEach(lineConsumer);
+    }
+  }
+
   private void joinAmbiguousLines(
       List<List<String>> retracedResult, Consumer<String> joinedConsumer) {
     if (retracedResult.isEmpty()) {
diff --git a/src/main/java/com/android/tools/r8/utils/InternalOptions.java b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
index e74dfd9..2612127 100644
--- a/src/main/java/com/android/tools/r8/utils/InternalOptions.java
+++ b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
@@ -143,7 +143,7 @@
     }
   }
 
-  public static final CfVersion SUPPORTED_CF_VERSION = CfVersion.V17;
+  public static final CfVersion SUPPORTED_CF_VERSION = CfVersion.V19;
 
   public static final int SUPPORTED_DEX_VERSION =
       AndroidApiLevel.LATEST.getDexVersion().getIntValue();
@@ -1870,7 +1870,8 @@
     public boolean allowInvokeErrors = false;
     public boolean allowUnnecessaryDontWarnWildcards = true;
     public boolean allowUnusedDontWarnRules = true;
-    public boolean reportUnusedProguardConfigurationRules = false;
+    public boolean reportUnusedProguardConfigurationRules =
+        System.getProperty("com.android.tools.r8.reportUnusedProguardConfigurationRules") != null;
     public boolean alwaysUseExistingAccessInfoCollectionsInMemberRebinding = true;
     public boolean alwaysUsePessimisticRegisterAllocation = false;
     public boolean enableCheckCastAndInstanceOfRemoval = true;
@@ -1878,7 +1879,8 @@
     public boolean enableInvokeSuperToInvokeVirtualRewriting = true;
     public boolean enableMultiANewArrayDesugaringForClassFiles = false;
     public boolean enableSwitchToIfRewriting = true;
-    public boolean enableEnumUnboxingDebugLogs = false;
+    public boolean enableEnumUnboxingDebugLogs =
+        System.getProperty("com.android.tools.r8.enableEnumUnboxingDebugLogs") != null;
     public boolean forceRedundantConstNumberRemoval = false;
     public boolean enableExperimentalDesugaredLibraryKeepRuleGenerator = false;
     public boolean invertConditionals = false;
diff --git a/src/test/java/com/android/tools/r8/FailCompilationOnFutureVersionsTest.java b/src/test/java/com/android/tools/r8/FailCompilationOnFutureVersionsTest.java
index c71ca8b..f7be6ca 100644
--- a/src/test/java/com/android/tools/r8/FailCompilationOnFutureVersionsTest.java
+++ b/src/test/java/com/android/tools/r8/FailCompilationOnFutureVersionsTest.java
@@ -79,14 +79,15 @@
                 diagnotics.assertErrorsCount(1);
                 assertThat(
                     diagnotics.getErrors().get(0).getDiagnosticMessage(),
-                    containsString("Unsupported class file version: " + UNSUPPORTED_CF_VERSION));
+                    containsString(
+                        "Unsupported class file major version " + UNSUPPORTED_CF_VERSION));
                 assertTrue(
                     diagnotics.getErrors().stream()
                         .allMatch(
                             s ->
                                 s.getDiagnosticMessage()
                                     .toLowerCase()
-                                    .contains("unsupported class file version")));
+                                    .contains("unsupported class file major version")));
               });
     } catch (CompilationFailedException e) {
       return;
diff --git a/src/test/java/com/android/tools/r8/SupportedClassFileVersions.java b/src/test/java/com/android/tools/r8/SupportedClassFileVersions.java
new file mode 100644
index 0000000..2d6e5b2
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/SupportedClassFileVersions.java
@@ -0,0 +1,92 @@
+// Copyright (c) 2022, 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;
+
+import com.android.tools.r8.cf.CfVersion;
+import java.util.List;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+
+@RunWith(Parameterized.class)
+public class SupportedClassFileVersions extends TestBase implements Opcodes {
+
+  @Parameter(0)
+  public TestParameters parameters;
+
+  @Parameter(1)
+  public CfVersion version;
+
+  @Parameters(name = "{0}, CF version = {1}")
+  public static List<Object[]> data() {
+    return buildParameters(
+        getTestParameters().withAllRuntimes().withAllApiLevelsAlsoForCf().build(), CfVersion.all());
+  }
+
+  @Test
+  public void testDesugar() throws Exception {
+    testForDesugaring(parameters)
+        .addProgramClassFileData(dump(version))
+        .run(parameters.getRuntime(), "Test")
+        .applyIf(
+            c ->
+                DesugarTestConfiguration.isNotDesugared(c) // This implies CF runtime.
+                    && version.major() > parameters.asCfRuntime().getVm().getClassfileVersion(),
+            r -> r.assertFailureWithErrorThatThrows(UnsupportedClassVersionError.class),
+            r -> r.assertSuccessWithOutputLines("Hello, world!"));
+  }
+
+  @Test
+  public void testR8() throws Exception {
+    testForR8(parameters.getBackend())
+        .addProgramClassFileData(dump(version))
+        .addKeepMainRule("Test")
+        .setMinApi(parameters.getApiLevel())
+        .run(parameters.getRuntime(), "Test")
+        .applyIf(
+            parameters.isCfRuntime()
+                && version.major() > parameters.asCfRuntime().getVm().getClassfileVersion(),
+            r -> r.assertFailureWithErrorThatThrows(UnsupportedClassVersionError.class),
+            r -> r.assertSuccessWithOutputLines("Hello, world!"));
+  }
+
+  public static byte[] dump(CfVersion version) {
+    // Generate a class file with a version higher than the supported one.
+    ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
+    MethodVisitor methodVisitor;
+    classWriter.visit(
+        version.raw(), ACC_PUBLIC + ACC_SUPER, "Test", null, "java/lang/Object", null);
+    {
+      methodVisitor = classWriter.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
+      methodVisitor.visitCode();
+      methodVisitor.visitVarInsn(ALOAD, 0);
+      methodVisitor.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
+      methodVisitor.visitInsn(RETURN);
+      methodVisitor.visitMaxs(1, 1);
+      methodVisitor.visitEnd();
+    }
+
+    {
+      methodVisitor =
+          classWriter.visitMethod(
+              ACC_PUBLIC | ACC_STATIC, "main", "([Ljava/lang/String;)V", null, null);
+      methodVisitor.visitCode();
+      methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+      methodVisitor.visitLdcInsn("Hello, world!");
+      methodVisitor.visitMethodInsn(
+          INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/Object;)V", false);
+      methodVisitor.visitInsn(RETURN);
+      methodVisitor.visitMaxs(2, 1);
+      methodVisitor.visitEnd();
+    }
+    classWriter.visitEnd();
+    return classWriter.toByteArray();
+  }
+}
diff --git a/src/test/java/com/android/tools/r8/cf/ValidateInputWithAsmTest.java b/src/test/java/com/android/tools/r8/cf/ValidateInputWithAsmTest.java
new file mode 100644
index 0000000..e0ffc56
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/cf/ValidateInputWithAsmTest.java
@@ -0,0 +1,89 @@
+// Copyright (c) 2022, 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.cf;
+
+import static com.android.tools.r8.DiagnosticsMatcher.diagnosticMessage;
+import static org.hamcrest.CoreMatchers.containsString;
+
+import com.android.tools.r8.CompilationFailedException;
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.TestCompilerBuilder;
+import com.android.tools.r8.TestDiagnosticMessages;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.TestParametersCollection;
+import com.android.tools.r8.transformers.MethodTransformer;
+import com.android.tools.r8.utils.AndroidApiLevel;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
+
+@RunWith(Parameterized.class)
+public class ValidateInputWithAsmTest extends TestBase {
+
+  @Parameter() public TestParameters parameters;
+
+  @Parameters(name = "{0}")
+  public static TestParametersCollection data() {
+    return getTestParameters().withNoneRuntime().build();
+  }
+
+  @Test(expected = CompilationFailedException.class)
+  public void testD8() throws Exception {
+    testForD8(Backend.DEX)
+        .apply(this::configure)
+        .compileWithExpectedDiagnostics(this::checkDiagnostics);
+  }
+
+  @Test(expected = CompilationFailedException.class)
+  public void testR8() throws Exception {
+    testForR8(Backend.DEX)
+        .apply(this::configure)
+        .addKeepMainRule(TestClass.class)
+        .compileWithExpectedDiagnostics(this::checkDiagnostics);
+  }
+
+  private void configure(TestCompilerBuilder<?, ?, ?, ?, ?> builder) throws Exception {
+    builder
+        .addProgramClassFileData(getInvalidClass())
+        .setMinApi(AndroidApiLevel.B)
+        .addOptionsModification(options -> options.testing.verifyInputs = true);
+  }
+
+  private void checkDiagnostics(TestDiagnosticMessages diagnostics) {
+    diagnostics
+        .assertOnlyErrors()
+        .assertAllErrorsMatch(
+            diagnosticMessage(containsString("INVOKEVIRTUAL can't be used with interfaces")));
+  }
+
+  private byte[] getInvalidClass() throws Exception {
+    return transformer(TestClass.class)
+        .addMethodTransformer(
+            new MethodTransformer() {
+              @Override
+              public void visitMethodInsn(
+                  final int opcode,
+                  final String owner,
+                  final String name,
+                  final String descriptor,
+                  final boolean isInterface) {
+                if (owner.endsWith("PrintStream")) {
+                  super.visitMethodInsn(opcode, owner, name, descriptor, true);
+                } else {
+                  super.visitMethodInsn(opcode, owner, name, descriptor, isInterface);
+                }
+              }
+            })
+        .transform();
+  }
+
+  static class TestClass {
+
+    public static void main(String[] args) {
+      System.out.println("Hello, world!");
+    }
+  }
+}
diff --git a/src/test/java/com/android/tools/r8/cf/stackmap/InvalidStackHeightTest.java b/src/test/java/com/android/tools/r8/cf/stackmap/InvalidStackHeightTest.java
index 41c05a3..f411d91 100644
--- a/src/test/java/com/android/tools/r8/cf/stackmap/InvalidStackHeightTest.java
+++ b/src/test/java/com/android/tools/r8/cf/stackmap/InvalidStackHeightTest.java
@@ -5,8 +5,6 @@
 package com.android.tools.r8.cf.stackmap;
 
 import static org.hamcrest.CoreMatchers.containsString;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
 import static org.junit.Assume.assumeTrue;
 
 import com.android.tools.r8.CompilationFailedException;
@@ -81,23 +79,6 @@
         containsString("The max stack height of 1 is violated"));
   }
 
-  @Test()
-  public void testR8InputVerification() throws Exception {
-    try {
-      testForR8(parameters.getBackend())
-          .addProgramClassFileData(getMainWithChangedMaxStackHeight())
-          .enableInliningAnnotations()
-          .addKeepMainRule(Main.class)
-          .setMinApi(parameters.getApiLevel())
-          .addOptionsModification(options -> options.testing.verifyInputs = true)
-          .compile();
-    } catch (CompilationFailedException e) {
-      assertTrue(e.getCause().getMessage().contains("Insufficient maximum stack size"));
-      return;
-    }
-    fail("Should always throw");
-  }
-
   public byte[] getMainWithChangedMaxStackHeight() throws Exception {
     return transformer(Main.class).setMaxStackHeight(MethodPredicate.onName("main"), 1).transform();
   }
diff --git a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/gson/ConcurrentHashMapFileSerializationTest.java b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/gson/ConcurrentHashMapFileSerializationTest.java
index 3afc61c..1009f56 100644
--- a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/gson/ConcurrentHashMapFileSerializationTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/gson/ConcurrentHashMapFileSerializationTest.java
@@ -4,6 +4,7 @@
 
 package com.android.tools.r8.desugar.desugaredlibrary.gson;
 
+import static com.android.tools.r8.desugar.desugaredlibrary.gson.GsonDesugaredLibraryTestUtils.uniqueName;
 import static com.android.tools.r8.desugar.desugaredlibrary.test.CompilationSpecification.DEFAULT_SPECIFICATIONS;
 import static com.android.tools.r8.desugar.desugaredlibrary.test.LibraryDesugaringSpecification.getJdk8Jdk11;
 import static org.junit.Assert.assertFalse;
@@ -72,7 +73,10 @@
         .compile()
         .inspectL8(this::assertVersionUID)
         .withArt6Plus64BitsLib()
-        .run(parameters.getRuntime(), Executor.class)
+        .run(
+            parameters.getRuntime(),
+            Executor.class,
+            uniqueName(temp, libraryDesugaringSpecification, compilationSpecification, parameters))
         .assertSuccessWithOutput(EXPECTED_RESULT);
   }
 
@@ -90,15 +94,15 @@
   @SuppressWarnings("MismatchedQueryAndUpdateOfCollection")
   static class Executor {
     public static void main(String[] args) throws Exception {
-      chmTest();
+      chmTest(args[0]);
     }
 
     @SuppressWarnings("unchecked")
-    private static void chmTest() throws IOException, ClassNotFoundException {
+    private static void chmTest(String uniqueName) throws IOException, ClassNotFoundException {
       ConcurrentHashMap<String, String> map = new ConcurrentHashMap<>();
       map.put("k1", "v1");
       map.put("k2", "v2");
-      File file = new File("testTemp");
+      File file = new File(uniqueName);
 
       FileOutputStream fos = new FileOutputStream(file);
       ObjectOutputStream oos = new ObjectOutputStream(fos);
diff --git a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/gson/GsonAllMapsTest.java b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/gson/GsonAllMapsTest.java
index e7421fe..c861001 100644
--- a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/gson/GsonAllMapsTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/gson/GsonAllMapsTest.java
@@ -3,10 +3,13 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8.desugar.desugaredlibrary.gson;
 
+import static com.android.tools.r8.desugar.desugaredlibrary.gson.GsonDesugaredLibraryTestUtils.GSON_2_8_1_JAR;
+import static com.android.tools.r8.desugar.desugaredlibrary.gson.GsonDesugaredLibraryTestUtils.GSON_CONFIGURATION;
 import static com.android.tools.r8.desugar.desugaredlibrary.test.CompilationSpecification.DEFAULT_SPECIFICATIONS;
 import static com.android.tools.r8.desugar.desugaredlibrary.test.LibraryDesugaringSpecification.getJdk8Jdk11;
 
 import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.desugar.desugaredlibrary.DesugaredLibraryTestBase;
 import com.android.tools.r8.desugar.desugaredlibrary.test.CompilationSpecification;
 import com.android.tools.r8.desugar.desugaredlibrary.test.LibraryDesugaringSpecification;
 import java.util.List;
@@ -17,7 +20,7 @@
 import org.junit.runners.Parameterized.Parameters;
 
 @RunWith(Parameterized.class)
-public class GsonAllMapsTest extends GsonDesugaredLibraryTestBase {
+public class GsonAllMapsTest extends DesugaredLibraryTestBase {
 
   private final TestParameters parameters;
   private final LibraryDesugaringSpecification libraryDesugaringSpecification;
diff --git a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/gson/GsonDesugaredLibraryTestBase.java b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/gson/GsonDesugaredLibraryTestBase.java
deleted file mode 100644
index 1904ff7..0000000
--- a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/gson/GsonDesugaredLibraryTestBase.java
+++ /dev/null
@@ -1,14 +0,0 @@
-// 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.desugar.desugaredlibrary.gson;
-
-import com.android.tools.r8.desugar.desugaredlibrary.DesugaredLibraryTestBase;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-
-public abstract class GsonDesugaredLibraryTestBase extends DesugaredLibraryTestBase {
-  protected static final Path GSON_CONFIGURATION =
-      Paths.get("src/test/java/com/android/tools/r8/desugar/desugaredlibrary/gson/gson.cfg");
-  protected static final Path GSON_2_8_1_JAR = Paths.get("third_party/iosched_2019/gson-2.8.1.jar");
-}
diff --git a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/gson/GsonDesugaredLibraryTestUtils.java b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/gson/GsonDesugaredLibraryTestUtils.java
new file mode 100644
index 0000000..b07f7b9
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/gson/GsonDesugaredLibraryTestUtils.java
@@ -0,0 +1,36 @@
+// Copyright (c) 2022, 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.desugar.desugaredlibrary.gson;
+
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.desugar.desugaredlibrary.test.CompilationSpecification;
+import com.android.tools.r8.desugar.desugaredlibrary.test.LibraryDesugaringSpecification;
+import java.io.IOException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import org.junit.rules.TemporaryFolder;
+
+public abstract class GsonDesugaredLibraryTestUtils {
+
+  static final Path GSON_CONFIGURATION =
+      Paths.get("src/test/java/com/android/tools/r8/desugar/desugaredlibrary/gson/gson.cfg");
+  static final Path GSON_2_8_1_JAR = Paths.get("third_party/iosched_2019/gson-2.8.1.jar");
+
+  static String uniqueName(
+      TemporaryFolder temp,
+      LibraryDesugaringSpecification libraryDesugaringSpecification,
+      CompilationSpecification compilationSpecification,
+      TestParameters parameters)
+      throws IOException {
+    return temp.newFolder("test_serialization").toString()
+        + "/test_"
+        + libraryDesugaringSpecification.toString()
+        + "_"
+        + compilationSpecification.toString()
+        + "_"
+        + parameters.getRuntime()
+        + "_"
+        + parameters.getApiLevel();
+  }
+}
diff --git a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/gson/GsonOptionalTest.java b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/gson/GsonOptionalTest.java
index d42473c..d1a5a9e 100644
--- a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/gson/GsonOptionalTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/gson/GsonOptionalTest.java
@@ -3,10 +3,13 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8.desugar.desugaredlibrary.gson;
 
+import static com.android.tools.r8.desugar.desugaredlibrary.gson.GsonDesugaredLibraryTestUtils.GSON_2_8_1_JAR;
+import static com.android.tools.r8.desugar.desugaredlibrary.gson.GsonDesugaredLibraryTestUtils.GSON_CONFIGURATION;
 import static com.android.tools.r8.desugar.desugaredlibrary.test.CompilationSpecification.DEFAULT_SPECIFICATIONS;
 import static com.android.tools.r8.desugar.desugaredlibrary.test.LibraryDesugaringSpecification.getJdk8Jdk11;
 
 import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.desugar.desugaredlibrary.DesugaredLibraryTestBase;
 import com.android.tools.r8.desugar.desugaredlibrary.test.CompilationSpecification;
 import com.android.tools.r8.desugar.desugaredlibrary.test.LibraryDesugaringSpecification;
 import com.android.tools.r8.utils.StringUtils;
@@ -18,7 +21,7 @@
 import org.junit.runners.Parameterized.Parameters;
 
 @RunWith(Parameterized.class)
-public class GsonOptionalTest extends GsonDesugaredLibraryTestBase {
+public class GsonOptionalTest extends DesugaredLibraryTestBase {
 
   private final TestParameters parameters;
   private final LibraryDesugaringSpecification libraryDesugaringSpecification;
diff --git a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/gson/MyMapFileSerializationTest.java b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/gson/MyMapFileSerializationTest.java
index 3c85888..2387d64 100644
--- a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/gson/MyMapFileSerializationTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/gson/MyMapFileSerializationTest.java
@@ -4,6 +4,7 @@
 
 package com.android.tools.r8.desugar.desugaredlibrary.gson;
 
+import static com.android.tools.r8.desugar.desugaredlibrary.gson.GsonDesugaredLibraryTestUtils.uniqueName;
 import static com.android.tools.r8.desugar.desugaredlibrary.test.CompilationSpecification.DEFAULT_SPECIFICATIONS;
 import static com.android.tools.r8.desugar.desugaredlibrary.test.LibraryDesugaringSpecification.getJdk8Jdk11;
 
@@ -64,20 +65,13 @@
         .noMinification()
         .compile()
         .withArt6Plus64BitsLib()
-        .run(parameters.getRuntime(), Executor.class, uniqueName())
+        .run(
+            parameters.getRuntime(),
+            Executor.class,
+            uniqueName(temp, libraryDesugaringSpecification, compilationSpecification, parameters))
         .assertSuccessWithOutput(EXPECTED_RESULT);
   }
 
-  private String uniqueName() {
-    return libraryDesugaringSpecification.toString()
-        + "_"
-        + compilationSpecification.toString()
-        + "_"
-        + parameters.getRuntime()
-        + "_"
-        + parameters.getApiLevel();
-  }
-
   @SuppressWarnings("MismatchedQueryAndUpdateOfCollection")
   static class Executor {
 
@@ -86,10 +80,7 @@
       MyMap<String, String> map = new MyMap<>();
       map.put("k1", "v1");
       map.put("k2", "v2");
-      // It seems the FileSystem is shared across multiple VM runs at least on some VMs.
-      // There is no easy way to create a temp file that works on all VM/configurations.
-      // We pass a unique string as parameter that we use for the file name.
-      File file = new File("test_" + args[0]);
+      File file = new File(args[0]);
 
       FileOutputStream fos = new FileOutputStream(file);
       ObjectOutputStream oos = new ObjectOutputStream(fos);
diff --git a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/gson/TimeSerializationTest.java b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/gson/TimeSerializationTest.java
new file mode 100644
index 0000000..5c87fb9
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/gson/TimeSerializationTest.java
@@ -0,0 +1,117 @@
+// Copyright (c) 2022, 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.desugar.desugaredlibrary.gson;
+
+import static com.android.tools.r8.desugar.desugaredlibrary.gson.GsonDesugaredLibraryTestUtils.uniqueName;
+import static com.android.tools.r8.desugar.desugaredlibrary.test.CompilationSpecification.DEFAULT_SPECIFICATIONS;
+import static com.android.tools.r8.desugar.desugaredlibrary.test.LibraryDesugaringSpecification.getJdk8Jdk11;
+
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.ToolHelper.DexVm.Version;
+import com.android.tools.r8.desugar.desugaredlibrary.DesugaredLibraryTestBase;
+import com.android.tools.r8.desugar.desugaredlibrary.test.CompilationSpecification;
+import com.android.tools.r8.desugar.desugaredlibrary.test.LibraryDesugaringSpecification;
+import com.android.tools.r8.utils.StringUtils;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.time.ZoneId;
+import java.time.ZoneOffset;
+import java.time.ZonedDateTime;
+import java.util.List;
+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 TimeSerializationTest extends DesugaredLibraryTestBase {
+
+  private final TestParameters parameters;
+  private final LibraryDesugaringSpecification libraryDesugaringSpecification;
+  private final CompilationSpecification compilationSpecification;
+
+  private static final String EXPECTED_RESULT =
+      StringUtils.lines(
+          "Z",
+          "GMT",
+          "2008-06-01T20:30:42.000000111Z[GMT]",
+          "Z",
+          "GMT",
+          "2008-06-01T20:30:42.000000111Z[GMT]");
+
+  @Parameters(name = "{0}, spec: {1}, {2}")
+  public static List<Object[]> data() {
+    return buildParameters(
+        // TODO(b/134732760): Skip Android 4.4.4 due to missing libjavacrypto.
+        getTestParameters()
+            .withDexRuntime(Version.V4_0_4)
+            .withDexRuntimesStartingFromIncluding(Version.V5_1_1)
+            .withAllApiLevels()
+            .build(),
+        getJdk8Jdk11(),
+        DEFAULT_SPECIFICATIONS);
+  }
+
+  public TimeSerializationTest(
+      TestParameters parameters,
+      LibraryDesugaringSpecification libraryDesugaringSpecification,
+      CompilationSpecification compilationSpecification) {
+    this.parameters = parameters;
+    this.libraryDesugaringSpecification = libraryDesugaringSpecification;
+    this.compilationSpecification = compilationSpecification;
+  }
+
+  @Test
+  public void testZonedDateTimeSerialization() throws Throwable {
+    testForDesugaredLibrary(parameters, libraryDesugaringSpecification, compilationSpecification)
+        .addInnerClasses(TimeSerializationTest.class)
+        .addKeepMainRule(Executor.class)
+        .compile()
+        .withArt6Plus64BitsLib()
+        .run(
+            parameters.getRuntime(),
+            Executor.class,
+            uniqueName(temp, libraryDesugaringSpecification, compilationSpecification, parameters))
+        .assertSuccessWithOutput(EXPECTED_RESULT);
+  }
+
+  @SuppressWarnings("MismatchedQueryAndUpdateOfCollection")
+  static class Executor {
+
+    @SuppressWarnings("unchecked")
+    public static void main(String[] args) throws Exception {
+      ZoneOffset offset = ZoneOffset.UTC;
+      System.out.println(offset);
+      ZoneId gmt = ZoneId.of("GMT");
+      System.out.println(gmt);
+      ZonedDateTime dateTime = ZonedDateTime.of(2008, 6, 1, 20, 30, 42, 111, gmt);
+      System.out.println(dateTime);
+      File file = new File(args[0]);
+
+      FileOutputStream fos = new FileOutputStream(file);
+      ObjectOutputStream oos = new ObjectOutputStream(fos);
+      oos.writeObject(offset);
+      oos.writeObject(gmt);
+      oos.writeObject(dateTime);
+      oos.close();
+      fos.close();
+
+      FileInputStream fis = new FileInputStream(file);
+      ObjectInputStream ois = new ObjectInputStream(fis);
+      ZoneOffset newOffset = (ZoneOffset) ois.readObject();
+      ZoneId newGmt = (ZoneId) ois.readObject();
+      ZonedDateTime newDateTime = (ZonedDateTime) ois.readObject();
+      fis.close();
+      ois.close();
+
+      System.out.println(newOffset);
+      System.out.println(newGmt);
+      System.out.println(newDateTime);
+    }
+  }
+}
diff --git a/src/test/java/com/android/tools/r8/desugar/records/EmptyRecordTest.java b/src/test/java/com/android/tools/r8/desugar/records/EmptyRecordTest.java
index 2554cf0..75dc0c4 100644
--- a/src/test/java/com/android/tools/r8/desugar/records/EmptyRecordTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/records/EmptyRecordTest.java
@@ -11,7 +11,6 @@
 import com.android.tools.r8.TestRuntime.CfVm;
 import com.android.tools.r8.utils.BooleanUtils;
 import com.android.tools.r8.utils.StringUtils;
-import com.android.tools.r8.utils.codeinspector.AssertUtils;
 import java.util.List;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -66,28 +65,22 @@
 
   @Test
   public void testR8() throws Exception {
-    // TODO(b/233857841): Should always succeed.
-    AssertUtils.assertFailsCompilationIf(
-        parameters.isDexRuntime() && !enableMinification,
-        () ->
-            testForR8(parameters.getBackend())
-                .addProgramClassFileData(PROGRAM_DATA)
-                .addKeepMainRule(MAIN_TYPE)
-                .applyIf(
-                    parameters.isCfRuntime(),
-                    testBuilder ->
-                        testBuilder.addLibraryFiles(RecordTestUtils.getJdk15LibraryFiles(temp)))
-                .minification(enableMinification)
-                .setMinApi(parameters.getApiLevel())
-                .compile()
-                .applyIf(
-                    parameters.isCfRuntime(),
-                    compileResult ->
-                        compileResult.inspect(RecordTestUtils::assertRecordsAreRecords))
-                .run(parameters.getRuntime(), MAIN_TYPE)
-                .assertSuccessWithOutput(
-                    enableMinification
-                        ? EXPECTED_RESULT_R8_MINIFICATION
-                        : EXPECTED_RESULT_R8_NO_MINIFICATION));
+    testForR8(parameters.getBackend())
+        .addProgramClassFileData(PROGRAM_DATA)
+        .addKeepMainRule(MAIN_TYPE)
+        .applyIf(
+            parameters.isCfRuntime(),
+            testBuilder -> testBuilder.addLibraryFiles(RecordTestUtils.getJdk15LibraryFiles(temp)))
+        .minification(enableMinification)
+        .setMinApi(parameters.getApiLevel())
+        .compile()
+        .applyIf(
+            parameters.isCfRuntime(),
+            compileResult -> compileResult.inspect(RecordTestUtils::assertRecordsAreRecords))
+        .run(parameters.getRuntime(), MAIN_TYPE)
+        .assertSuccessWithOutput(
+            enableMinification
+                ? EXPECTED_RESULT_R8_MINIFICATION
+                : EXPECTED_RESULT_R8_NO_MINIFICATION);
   }
 }
diff --git a/src/test/java/com/android/tools/r8/desugar/records/RecordShrinkFieldTest.java b/src/test/java/com/android/tools/r8/desugar/records/RecordShrinkFieldTest.java
index 2c426fc..a8073f5 100644
--- a/src/test/java/com/android/tools/r8/desugar/records/RecordShrinkFieldTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/records/RecordShrinkFieldTest.java
@@ -8,11 +8,13 @@
 
 import com.android.tools.r8.TestBase;
 import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.utils.BooleanUtils;
 import com.android.tools.r8.utils.StringUtils;
 import com.android.tools.r8.utils.codeinspector.ClassSubject;
 import com.android.tools.r8.utils.codeinspector.CodeInspector;
 import java.nio.file.Path;
 import java.util.List;
+import org.junit.Assume;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.Parameterized;
@@ -23,26 +25,33 @@
   private static final String RECORD_NAME = "RecordShrinkField";
   private static final byte[][] PROGRAM_DATA = RecordTestUtils.getProgramData(RECORD_NAME);
   private static final String MAIN_TYPE = RecordTestUtils.getMainType(RECORD_NAME);
-  private static final String EXPECTED_RESULT =
-      StringUtils.lines("%s[unused=-1, name=Jane Doe, age=42]", "%s[unused=-1, name=Bob, age=42]");
+
   private static final String EXPECTED_RESULT_D8 =
-      String.format(EXPECTED_RESULT, "Person", "Person");
+      StringUtils.lines(
+          "Person[unused=-1, name=Jane Doe, age=42]", "Person[unused=-1, name=Bob, age=42]");
   private static final String EXPECTED_RESULT_R8 = StringUtils.lines("a[a=Jane Doe]", "a[a=Bob]");
+  private static final String EXPECTED_RESULT_R8_NO_MINIFICATION =
+      StringUtils.lines(
+          "RecordShrinkField$Person[name=Jane Doe]", "RecordShrinkField$Person[name=Bob]");
 
   private final TestParameters parameters;
+  private final boolean minifying;
 
-  public RecordShrinkFieldTest(TestParameters parameters) {
+  public RecordShrinkFieldTest(TestParameters parameters, boolean minifying) {
     this.parameters = parameters;
+    this.minifying = minifying;
   }
 
-  @Parameterized.Parameters(name = "{0}")
+  @Parameterized.Parameters(name = "{0}, minifying: {1}")
   public static List<Object[]> data() {
     return buildParameters(
-        getTestParameters().withDexRuntimes().withAllApiLevelsAlsoForCf().build());
+        getTestParameters().withDexRuntimes().withAllApiLevelsAlsoForCf().build(),
+        BooleanUtils.values());
   }
 
   @Test
   public void testD8() throws Exception {
+    Assume.assumeTrue("Only valid in R8", minifying);
     testForD8(parameters.getBackend())
         .addProgramClassFileData(PROGRAM_DATA)
         .setMinApi(parameters.getApiLevel())
@@ -57,10 +66,12 @@
         .addProgramClassFileData(PROGRAM_DATA)
         .setMinApi(parameters.getApiLevel())
         .addKeepMainRule(MAIN_TYPE)
+        .minification(minifying)
         .compile()
         .inspect(this::assertSingleField)
         .run(parameters.getRuntime(), MAIN_TYPE)
-        .assertSuccessWithOutput(EXPECTED_RESULT_R8);
+        .assertSuccessWithOutput(
+            minifying ? EXPECTED_RESULT_R8 : EXPECTED_RESULT_R8_NO_MINIFICATION);
   }
 
   @Test
@@ -70,6 +81,7 @@
             .addProgramClassFileData(PROGRAM_DATA)
             .setMinApi(parameters.getApiLevel())
             .addKeepMainRule(MAIN_TYPE)
+            .minification(minifying)
             .addLibraryFiles(RecordTestUtils.getJdk15LibraryFiles(temp))
             .compile()
             .writeToZip();
@@ -77,14 +89,17 @@
         .addProgramFiles(desugared)
         .setMinApi(parameters.getApiLevel())
         .addKeepMainRule(MAIN_TYPE)
+        .minification(minifying)
         .compile()
         .inspect(this::assertSingleField)
         .run(parameters.getRuntime(), MAIN_TYPE)
-        .assertSuccessWithOutput(EXPECTED_RESULT_R8);
+        .assertSuccessWithOutput(
+            minifying ? EXPECTED_RESULT_R8 : EXPECTED_RESULT_R8_NO_MINIFICATION);
   }
 
   private void assertSingleField(CodeInspector inspector) {
-    ClassSubject recordClass = inspector.clazz("records.a");
+    ClassSubject recordClass =
+        inspector.clazz(minifying ? "records.a" : "records.RecordShrinkField$Person");
     assertEquals(1, recordClass.allInstanceFields().size());
     assertEquals(
         "java.lang.String", recordClass.allInstanceFields().get(0).getField().type().toString());
diff --git a/src/test/java/com/android/tools/r8/enumunboxing/NullAssignmentToArrayTypeEnumUnboxingTest.java b/src/test/java/com/android/tools/r8/enumunboxing/NullAssignmentToArrayTypeEnumUnboxingTest.java
new file mode 100644
index 0000000..947121d
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/enumunboxing/NullAssignmentToArrayTypeEnumUnboxingTest.java
@@ -0,0 +1,97 @@
+// Copyright (c) 2022, 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.enumunboxing;
+
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertTrue;
+
+import com.android.tools.r8.NeverInline;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.utils.codeinspector.ClassSubject;
+import com.android.tools.r8.utils.codeinspector.InstructionSubject;
+import com.android.tools.r8.utils.codeinspector.MethodSubject;
+import java.util.List;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
+
+/** Regression test for b/236618700. */
+@RunWith(Parameterized.class)
+public class NullAssignmentToArrayTypeEnumUnboxingTest extends EnumUnboxingTestBase {
+
+  @Parameter(0)
+  public TestParameters parameters;
+
+  @Parameter(1)
+  public boolean enumValueOptimization;
+
+  @Parameter(2)
+  public EnumKeepRules enumKeepRules;
+
+  @Parameters(name = "{0}, value opt.: {1}, keep: {2}")
+  public static List<Object[]> data() {
+    return enumUnboxingTestParameters();
+  }
+
+  @Test
+  public void test() throws Exception {
+    testForR8(parameters.getBackend())
+        .addInnerClasses(NullAssignmentToArrayTypeEnumUnboxingTest.class)
+        .addKeepMainRule(Main.class)
+        .addKeepRules(enumKeepRules.getKeepRules())
+        .addEnumUnboxingInspector(inspector -> inspector.assertUnboxed(MyEnum.class))
+        .enableInliningAnnotations()
+        .addOptionsModification(opt -> enableEnumOptions(opt, enumValueOptimization))
+        .setMinApi(parameters.getApiLevel())
+        .compile()
+        .inspect(
+            inspector -> {
+              ClassSubject mainClassSubject = inspector.clazz(Main.class);
+              assertThat(mainClassSubject, isPresent());
+
+              MethodSubject clinitMethodSubject = mainClassSubject.clinit();
+              assertThat(clinitMethodSubject, isPresent());
+              assertTrue(
+                  clinitMethodSubject
+                      .streamInstructions()
+                      .anyMatch(InstructionSubject::isFieldAccess));
+            })
+        .run(parameters.getRuntime(), Main.class)
+        .assertSuccessWithOutputLines("A");
+  }
+
+  static class Main {
+
+    static MyEnum[] e;
+
+    static {
+      System.currentTimeMillis(); // To preserve the null assignment below.
+      e = null;
+    }
+
+    public static void main(String[] args) {
+      setField();
+      getField();
+    }
+
+    @NeverInline
+    static void setField() {
+      e = new MyEnum[] {System.currentTimeMillis() > 0 ? MyEnum.A : MyEnum.B};
+    }
+
+    @NeverInline
+    static void getField() {
+      System.out.println(e[0].name());
+    }
+  }
+
+  enum MyEnum {
+    A,
+    B
+  }
+}
diff --git a/tools/asmifier.py b/tools/asmifier.py
index 2b6a799..ae7d1e6 100755
--- a/tools/asmifier.py
+++ b/tools/asmifier.py
@@ -10,7 +10,7 @@
 import sys
 import utils
 
-ASM_VERSION = '9.2'
+ASM_VERSION = '9.3'
 ASM_JAR = 'asm-' + ASM_VERSION + '.jar'
 ASM_UTIL_JAR = 'asm-util-' + ASM_VERSION + '.jar'