Fix bug when merging methods with default super method

Bug: 163311975
Change-Id: I46a0b4176758d7d19ff7354612fcf1e136d4c4fa
diff --git a/src/main/java/com/android/tools/r8/horizontalclassmerging/VirtualMethodMerger.java b/src/main/java/com/android/tools/r8/horizontalclassmerging/VirtualMethodMerger.java
index 7342124..96d1618 100644
--- a/src/main/java/com/android/tools/r8/horizontalclassmerging/VirtualMethodMerger.java
+++ b/src/main/java/com/android/tools/r8/horizontalclassmerging/VirtualMethodMerger.java
@@ -64,7 +64,7 @@
           appView
               .withLiveness()
               .appInfo()
-              .resolveMethodOnClass(template, target.superType)
+              .resolveMethodOnClass(template, target.getSuperType())
               .asSingleResolution();
       if (resolutionResult == null) {
         return null;
@@ -72,7 +72,14 @@
       if (resolutionResult.getResolvedMethod().isAbstract()) {
         return null;
       }
-      return resolutionResult.getResolvedMethod().method;
+      if (resolutionResult.getResolvedHolder().isInterface()) {
+        // Ensure that invoke virtual isn't called on an interface method.
+        return resolutionResult
+            .getResolvedMethod()
+            .getReference()
+            .withHolder(target.getSuperType(), appView.dexItemFactory());
+      }
+      return resolutionResult.getResolvedMethod().getReference();
     }
 
     public VirtualMethodMerger build(
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/MergedSuperMethodIsDefaultMethodTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/MergedSuperMethodIsDefaultMethodTest.java
new file mode 100644
index 0000000..2fa8996
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/MergedSuperMethodIsDefaultMethodTest.java
@@ -0,0 +1,83 @@
+// 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.classmerging.horizontal;
+
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
+import static com.android.tools.r8.utils.codeinspector.Matchers.notIf;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import com.android.tools.r8.CompilationFailedException;
+import com.android.tools.r8.NeverClassInline;
+import com.android.tools.r8.NeverInline;
+import com.android.tools.r8.NoVerticalClassMerging;
+import com.android.tools.r8.TestParameters;
+import java.io.IOException;
+import java.util.concurrent.ExecutionException;
+import org.junit.Test;
+
+public class MergedSuperMethodIsDefaultMethodTest extends HorizontalClassMergingTestBase {
+  public MergedSuperMethodIsDefaultMethodTest(
+      TestParameters parameters, boolean enableHorizontalClassMerging) {
+    super(parameters, enableHorizontalClassMerging);
+  }
+
+  @Test
+  public void testR8() throws IOException, CompilationFailedException, ExecutionException {
+    testForR8(parameters.getBackend())
+        .addInnerClasses(this.getClass())
+        .addOptionsModification(
+            options -> options.enableHorizontalClassMerging = enableHorizontalClassMerging)
+        .enableNoVerticalClassMergingAnnotations()
+        .enableNeverClassInliningAnnotations()
+        .enableInliningAnnotations()
+        .addKeepMainRule(Main.class)
+        .setMinApi(parameters.getApiLevel())
+        .run(parameters.getRuntime(), Main.class)
+        .assertSuccessWithOutputLines("I.foo")
+        .inspect(
+            codeInspector -> {
+              assertThat(codeInspector.clazz(I.class), isPresent());
+              assertThat(codeInspector.clazz(A.class), isPresent());
+              assertThat(codeInspector.clazz(B.class), isPresent());
+              assertThat(
+                  codeInspector.clazz(C.class), notIf(isPresent(), enableHorizontalClassMerging));
+            });
+  }
+
+  @NoVerticalClassMerging
+  public interface I {
+    @NeverInline
+    default void foo() {
+      System.out.println("I.foo");
+    }
+  }
+
+  public abstract static class A implements I {}
+
+  @NeverClassInline
+  public static class B extends A {
+
+    @Override
+    @NeverInline
+    public void foo() {
+      System.out.println("B.foo");
+    }
+  }
+
+  @NeverClassInline
+  public static class C extends A {}
+
+  public static class Main {
+
+    public static void main(String[] args) {
+      callA(args.length == 0 ? new C() : new B());
+    }
+
+    @NeverInline
+    private static void callA(A a) {
+      a.foo();
+    }
+  }
+}
diff --git a/src/test/java/com/android/tools/r8/resolution/virtualtargets/TargetInDefaultMethodTest.java b/src/test/java/com/android/tools/r8/resolution/virtualtargets/TargetInDefaultMethodTest.java
index 0afee04..c1f2301 100644
--- a/src/test/java/com/android/tools/r8/resolution/virtualtargets/TargetInDefaultMethodTest.java
+++ b/src/test/java/com/android/tools/r8/resolution/virtualtargets/TargetInDefaultMethodTest.java
@@ -86,7 +86,6 @@
 
   @Test
   public void testR8() throws IOException, CompilationFailedException, ExecutionException {
-    expectThrowsWithHorizontalClassMergingIf(parameters.isCfRuntime());
     testForR8(parameters.getBackend())
         .addInnerClasses(TargetInDefaultMethodTest.class)
         .enableInliningAnnotations()