Version 2.0.81

Cherry pick: Revised "Rewrite invoke-super targeting rewritten desugared library methods."
CL: https://r8-review.googlesource.com/c/r8/+/52004
Bug: 157806261

In addition this reverts the fix from 2.0.80.
Cherry pick: Revert "Rewrite invoke-super targeting rewritten desugared library methods."
CL: https://r8-review.googlesource.com/c/r8/+/52003

Change-Id: I4d2cdbdc4724a027ba553c2c2f68944f3562feb1
diff --git a/src/main/java/com/android/tools/r8/Version.java b/src/main/java/com/android/tools/r8/Version.java
index 6bb88a8..090e266 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.80";
+  public static final String LABEL = "2.0.81";
 
   private Version() {
   }
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/InterfaceMethodRewriter.java b/src/main/java/com/android/tools/r8/ir/desugar/InterfaceMethodRewriter.java
index 756243a..14f9443 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/InterfaceMethodRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/InterfaceMethodRewriter.java
@@ -255,14 +255,16 @@
             // exception but we can not report it as error since it can also be the intended
             // behavior.
             warnMissingType(encodedMethod.method, invokedMethod.holder);
-            continue;
-          }
-          if (!clazz.isInterface()) {
-            // Skip non-interface invokes.
-            continue;
-          }
-          if (!clazz.isLibraryClass()) {
-            // For program and classpath retarget call to an appropriate method of companion class.
+          } else if (clazz.isInterface() && !clazz.isLibraryClass()) {
+            // NOTE: we intentionally don't desugar super calls into interface methods
+            // coming from android.jar since it is only possible in case v24+ version
+            // of android.jar is provided.
+            //
+            // We assume such calls are properly guarded by if-checks like
+            //    'if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.XYZ) { ... }'
+            //
+            // WARNING: This may result in incorrect code on older platforms!
+            // Retarget call to an appropriate method of companion class.
             DexMethod amendedMethod =
                 amendDefaultMethod(
                     appInfo.definitionFor(encodedMethod.method.holder), invokedMethod);
@@ -270,32 +272,59 @@
                 new InvokeStatic(defaultAsMethodOfCompanionClass(amendedMethod),
                     invokeSuper.outValue(), invokeSuper.arguments()));
           } else {
-            // Rewriting is required if the super invoke resolves to a default method on the
-            // desugared library. Retarget or rewrite to the desugared library companion class.
-            DexEncodedMethod dexEncodedMethod =
-                targetForInvokeSuperDispatchToDefaultMethod(
-                    invokedMethod, clazz.asLibraryClass(), code.method.method.holder);
-            if (dexEncodedMethod != null) {
-              DexMethod retargetMethod =
-                  options.desugaredLibraryConfiguration.retargetMethod(
-                      dexEncodedMethod.method, appView);
-              if (retargetMethod == null) {
-                DexMethod originalCompanionMethod =
-                    instanceAsMethodOfCompanionClass(
-                        dexEncodedMethod.method, DEFAULT_METHOD_PREFIX, factory);
-                DexMethod companionMethod =
-                    factory.createMethod(
-                        getCompanionClassType(clazz.type),
-                        factory.protoWithDifferentFirstParameter(
-                            originalCompanionMethod.proto, clazz.type),
-                        originalCompanionMethod.name);
-                instructions.replaceCurrentInstruction(
-                    new InvokeStatic(
-                        companionMethod, invokeSuper.outValue(), invokeSuper.arguments()));
-              } else {
-                instructions.replaceCurrentInstruction(
-                    new InvokeStatic(
-                        retargetMethod, invokeSuper.outValue(), invokeSuper.arguments()));
+            DexType dexType = maximallySpecificEmulatedInterfaceOrNull(invokedMethod);
+            if (dexType == null) {
+              if (clazz.isInterface() && appView.rewritePrefix.hasRewrittenType(clazz.type)) {
+                DexEncodedMethod target =
+                    appView.appInfo().lookupSuperTarget(invokedMethod, code.method.method.holder);
+                if (target != null && target.isDefaultMethod()) {
+                  DexClass holder = appView.definitionFor(target.method.holder);
+                  if (holder.isLibraryClass() && holder.isInterface()) {
+                    instructions.replaceCurrentInstruction(
+                        new InvokeStatic(
+                            defaultAsMethodOfCompanionClass(target.method, factory),
+                            invokeSuper.outValue(),
+                            invokeSuper.arguments()));
+                  }
+                }
+              }
+            } else {
+              // That invoke super may not resolve since the super method may not be present
+              // since it's in the emulated interface. We need to force resolution. If it resolves
+              // to a library method, then it needs to be rewritten.
+              // If it resolves to a program overrides, the invoke-super can remain.
+              DexEncodedMethod dexEncodedMethod =
+                  appView
+                      .appInfo()
+                      .lookupSuperTarget(invokeSuper.getInvokedMethod(), code.method.method.holder);
+              if (dexEncodedMethod != null) {
+                DexClass dexClass = appView.definitionFor(dexEncodedMethod.method.holder);
+                if (dexClass != null && dexClass.isLibraryClass()) {
+                  // Rewriting is required because the super invoke resolves into a missing
+                  // method (method is on desugared library). Find out if it needs to be
+                  // retarget or if it just calls a companion class method and rewrite.
+                  DexMethod retargetMethod =
+                      options.desugaredLibraryConfiguration.retargetMethod(
+                          dexEncodedMethod.method, appView);
+                  if (retargetMethod == null) {
+                    DexMethod originalCompanionMethod =
+                        instanceAsMethodOfCompanionClass(
+                            dexEncodedMethod.method, DEFAULT_METHOD_PREFIX, factory);
+                    DexMethod companionMethod =
+                        factory.createMethod(
+                            getCompanionClassType(dexType),
+                            factory.protoWithDifferentFirstParameter(
+                                originalCompanionMethod.proto, dexType),
+                            originalCompanionMethod.name);
+                    instructions.replaceCurrentInstruction(
+                        new InvokeStatic(
+                            companionMethod, invokeSuper.outValue(), invokeSuper.arguments()));
+                  } else {
+                    instructions.replaceCurrentInstruction(
+                        new InvokeStatic(
+                            retargetMethod, invokeSuper.outValue(), invokeSuper.arguments()));
+                  }
+                }
               }
             }
           }
@@ -370,27 +399,6 @@
     }
   }
 
-  private DexEncodedMethod targetForInvokeSuperDispatchToDefaultMethod(
-      DexMethod invokedSuperMethod, DexLibraryClass holder, DexType context) {
-    assert invokedSuperMethod.holder == holder.type;
-    assert holder.isInterface();
-    DexEncodedMethod definition = holder.lookupMethod(invokedSuperMethod);
-    if (definition == null || !definition.isDefaultMethod()) {
-      return null;
-    }
-    // Only default methods on emulated interfaces or rewritten types need to be dealt with.
-    if (!emulatedMethods.contains(invokedSuperMethod.name)
-        && !appView.rewritePrefix.hasRewrittenType(holder.type)) {
-      return null;
-    }
-    DexEncodedMethod target = appView.appInfo().lookupSuperTarget(invokedSuperMethod, context);
-    DexClass targetHolder = appView.definitionFor(target.method.holder);
-    if (targetHolder == null || !targetHolder.isLibraryClass()) {
-      return null;
-    }
-    return target;
-  }
-
   private DexType maximallySpecificEmulatedInterfaceOrNull(DexMethod invokedMethod) {
     // Here we try to avoid doing the expensive look-up on all invokes.
     if (!emulatedMethods.contains(invokedMethod.name)) {