diff --git a/src/test/java/com/android/tools/r8/desugaring/interfacemethods/DefaultInterfaceMethodDesugaringWithStaticResolutionInvokeVirtualTest.java b/src/test/java/com/android/tools/r8/desugaring/interfacemethods/DefaultInterfaceMethodDesugaringWithStaticResolutionInvokeVirtualTest.java
new file mode 100644
index 0000000..1b51047
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/desugaring/interfacemethods/DefaultInterfaceMethodDesugaringWithStaticResolutionInvokeVirtualTest.java
@@ -0,0 +1,167 @@
+// 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.desugaring.interfacemethods;
+
+import static org.junit.Assert.assertEquals;
+
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.TestRunResult;
+import com.android.tools.r8.ToolHelper.DexVm;
+import com.android.tools.r8.ToolHelper.DexVm.Version;
+import com.android.tools.r8.utils.BooleanUtils;
+import com.android.tools.r8.utils.DescriptorUtils;
+import com.android.tools.r8.utils.StringUtils;
+import com.google.common.collect.ImmutableList;
+import java.util.Collection;
+import java.util.List;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.objectweb.asm.Opcodes;
+
+@RunWith(Parameterized.class)
+public class DefaultInterfaceMethodDesugaringWithStaticResolutionInvokeVirtualTest
+    extends TestBase {
+
+  private static final String EXPECTED = StringUtils.lines("I.m()");
+
+  private final TestParameters parameters;
+  private final boolean invalidInvoke;
+
+  @Parameterized.Parameters(name = "{0}, invalid:{1}")
+  public static List<Object[]> data() {
+    return buildParameters(
+        getTestParameters().withAllRuntimesAndApiLevels().build(), BooleanUtils.values());
+  }
+
+  public DefaultInterfaceMethodDesugaringWithStaticResolutionInvokeVirtualTest(
+      TestParameters parameters, boolean invalidInvoke) {
+    this.parameters = parameters;
+    this.invalidInvoke = invalidInvoke;
+  }
+
+  private Collection<Class<?>> getProgramClasses() {
+    return ImmutableList.of(I.class, A.class, C.class);
+  }
+
+  private Collection<byte[]> getProgramClassData() throws Exception {
+    return ImmutableList.of(
+        transformer(B.class)
+            .setAccessFlags(
+                B.class.getDeclaredMethod("m"),
+                flags -> {
+                  assert flags.isPublic();
+                  flags.unsetPublic();
+                  flags.setPrivate();
+                  flags.setStatic();
+                })
+            .transform(),
+        transformer(TestClass.class)
+            .transformMethodInsnInMethod(
+                "main",
+                (opcode, owner, name, descriptor, isInterface, continuation) -> {
+                  if (invalidInvoke && opcode == Opcodes.INVOKEVIRTUAL) {
+                    assertEquals("m", name);
+                    continuation.apply(
+                        opcode,
+                        DescriptorUtils.getBinaryNameFromJavaType(C.class.getTypeName()),
+                        name,
+                        descriptor,
+                        isInterface);
+                  } else {
+                    continuation.apply(opcode, owner, name, descriptor, isInterface);
+                  }
+                })
+            .transform());
+  }
+
+  @Test
+  public void testRuntime() throws Exception {
+    checkResult(
+        testForRuntime(parameters)
+            .addProgramClasses(getProgramClasses())
+            .addProgramClassFileData(getProgramClassData())
+            .run(parameters.getRuntime(), TestClass.class));
+  }
+
+  @Test
+  public void testR8() throws Exception {
+    checkResult(
+        testForR8(parameters.getBackend())
+            .addProgramClasses(getProgramClasses())
+            .addProgramClassFileData(getProgramClassData())
+            .addKeepAllClassesRule()
+            .setMinApi(parameters.getApiLevel())
+            .compile()
+            .run(parameters.getRuntime(), TestClass.class));
+  }
+
+  private void checkResult(TestRunResult result) {
+    // Invalid invoke case is where the invoke-virtual targets C.m.
+    if (invalidInvoke) {
+      // Up to 4.4 the exception for targeting a private static was ICCE.
+      if (isDexOlderThanOrEqual(Version.V4_4_4)) {
+        result.assertFailureWithErrorThatThrows(IncompatibleClassChangeError.class);
+        return;
+      }
+      // Then up to 6.0 the the runtime just ignores privates leading to incorrectly hitting I.m
+      if (isDexOlderThanOrEqual(Version.V6_0_1)) {
+        result.assertSuccessWithOutput(EXPECTED);
+        return;
+      }
+      // The expected behavior is IAE since the resolved method is private.
+      result.assertFailureWithErrorThatThrows(IllegalAccessError.class);
+      return;
+    }
+
+    // The non-invalid case is where the invoke-virtual targets A.m.
+
+    // In the successful case ART since 6.0 incorrectly throws IAE due to the private override.
+    if (unexpectedArtFailure()) {
+      result.assertFailureWithErrorThatThrows(IllegalAccessError.class);
+      return;
+    }
+
+    // The expected behavior is that the resolution of A.m will resolve and hit I.m.
+    result.assertSuccessWithOutput(EXPECTED);
+  }
+
+  private boolean isDexOlderThanOrEqual(Version version) {
+    return parameters.isDexRuntime()
+        && parameters.getRuntime().asDex().getVm().getVersion().isOlderThanOrEqual(version);
+  }
+
+  private boolean unexpectedArtFailure() {
+    return parameters.isDexRuntime()
+        && parameters.getRuntime().asDex().getVm().isNewerThan(DexVm.ART_6_0_1_HOST);
+  }
+
+  static class TestClass {
+
+    public static void main(String[] args) {
+      // Same as DefaultInterfaceMethodDesugaringWithStaticResolutionTest, but targets a class A.
+      A /* or C */ a = new C();
+      a.m();
+    }
+  }
+
+  interface I {
+
+    default void m() {
+      System.out.println("I.m()");
+    }
+  }
+
+  static class A implements I {}
+
+  static class B extends A {
+
+    public /* will be: private static */ void m() {
+      System.out.println("B.m()");
+    }
+  }
+
+  static class C extends B implements I {}
+}
