Allow synthetic methods to be abstract.

Fixes: 209475782
Change-Id: Ibfcab16460ca9d8e450fe501281002ab0c780de3
diff --git a/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java b/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java
index a68f038..abaa560 100644
--- a/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java
+++ b/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java
@@ -286,7 +286,6 @@
         .withBool(DexEncodedMember::isD8R8Synthesized)
         // TODO(b/171867022): Make signatures structural and include it in the definition.
         .withAssert(m -> m.genericSignature.hasNoSignature())
-        .withAssert(DexEncodedMethod::hasCode)
         .withCustomItem(
             DexEncodedMethod::getCode,
             DexEncodedMethod::compareCodeObject,
@@ -294,6 +293,13 @@
   }
 
   private static int compareCodeObject(Code code1, Code code2, CompareToVisitor visitor) {
+    if (code1 == code2) {
+      return 0;
+    }
+    if (code1 == null || code2 == null) {
+      // This call is to remain order consistent with the 'withNullableItem' code.
+      return visitor.visitBool(code1 != null, code2 != null);
+    }
     if (code1.isCfWritableCode() && code2.isCfWritableCode()) {
       return code1.asCfWritableCode().acceptCompareTo(code2.asCfWritableCode(), visitor);
     }
@@ -305,7 +311,10 @@
   }
 
   private static void hashCodeObject(Code code, HashingVisitor visitor) {
-    if (code.isCfWritableCode()) {
+    if (code == null) {
+      // The null code does not contribute to the hash. This should be distinct from non-null as
+      // code otherwise has a non-empty instruction payload.
+    } else if (code.isCfWritableCode()) {
       code.asCfWritableCode().acceptHashing(visitor);
     } else {
       assert code.isDexWritableCode();
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/membervaluepropagation/fields/TargetedButNotLiveLambdaAfterDevirtualizationTest.java b/src/test/java/com/android/tools/r8/ir/optimize/membervaluepropagation/fields/TargetedButNotLiveLambdaAfterDevirtualizationTest.java
index da325d1..999e2f4 100644
--- a/src/test/java/com/android/tools/r8/ir/optimize/membervaluepropagation/fields/TargetedButNotLiveLambdaAfterDevirtualizationTest.java
+++ b/src/test/java/com/android/tools/r8/ir/optimize/membervaluepropagation/fields/TargetedButNotLiveLambdaAfterDevirtualizationTest.java
@@ -8,7 +8,6 @@
 import com.android.tools.r8.TestBase;
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.TestParametersCollection;
-import com.android.tools.r8.utils.codeinspector.AssertUtils;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.Parameterized;
@@ -29,17 +28,14 @@
 
   @Test
   public void test() throws Exception {
-    AssertUtils.assertFailsCompilationIf(
-        parameters.isDexRuntime(),
-        () ->
-            testForR8(parameters.getBackend())
-                .addInnerClasses(getClass())
-                .addKeepMainRule(Main.class)
-                .enableInliningAnnotations()
-                .setMinApi(parameters.getApiLevel())
-                .compile()
-                .run(parameters.getRuntime(), Main.class)
-                .assertSuccessWithEmptyOutput());
+    testForR8(parameters.getBackend())
+        .addInnerClasses(getClass())
+        .addKeepMainRule(Main.class)
+        .enableInliningAnnotations()
+        .setMinApi(parameters.getApiLevel())
+        .compile()
+        .run(parameters.getRuntime(), Main.class)
+        .assertSuccessWithEmptyOutput();
   }
 
   static class Main {