Add test for superfluous monitor instructions

* Add getNode() helper for testing
* Always disable desugaring for CF backend

Bug: 73921688
Change-Id: I633138ab79e3df5bec414daea0ad41646c3c2e67
diff --git a/src/main/java/com/android/tools/r8/R8Command.java b/src/main/java/com/android/tools/r8/R8Command.java
index 7004d5f..9a61a9f 100644
--- a/src/main/java/com/android/tools/r8/R8Command.java
+++ b/src/main/java/com/android/tools/r8/R8Command.java
@@ -319,6 +319,9 @@
 
       assert getProgramConsumer() != null;
 
+      boolean desugaring =
+          (getProgramConsumer() instanceof ClassFileConsumer) ? false : !getDisableDesugaring();
+
       R8Command command =
           new R8Command(
               getAppBuilder().build(),
@@ -329,7 +332,7 @@
               getMode(),
               getMinApiLevel(),
               reporter,
-              !getDisableDesugaring(),
+              desugaring,
               configuration.isShrinking(),
               configuration.isObfuscating(),
               forceProguardCompatibility,
diff --git a/src/main/java/com/android/tools/r8/graph/JarCode.java b/src/main/java/com/android/tools/r8/graph/JarCode.java
index 62dc43f..16edb7a 100644
--- a/src/main/java/com/android/tools/r8/graph/JarCode.java
+++ b/src/main/java/com/android/tools/r8/graph/JarCode.java
@@ -60,6 +60,11 @@
     context.codeList.add(this);
   }
 
+  public MethodNode getNode() {
+    triggerDelayedParsingIfNeccessary();
+    return node;
+  }
+
   @Override
   public boolean isJarCode() {
     return true;
diff --git a/src/test/java/com/android/tools/r8/cf/SynchronizedNoopTest.java b/src/test/java/com/android/tools/r8/cf/SynchronizedNoopTest.java
new file mode 100644
index 0000000..c1d079e
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/cf/SynchronizedNoopTest.java
@@ -0,0 +1,13 @@
+/*
+ * Copyright (c) 2018, 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;
+
+public class SynchronizedNoopTest {
+  public static synchronized void noop() {
+    System.out.println("Foo");
+  }
+}
diff --git a/src/test/java/com/android/tools/r8/cf/SynchronizedNoopTestRunner.java b/src/test/java/com/android/tools/r8/cf/SynchronizedNoopTestRunner.java
new file mode 100644
index 0000000..20acb9f
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/cf/SynchronizedNoopTestRunner.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2018, 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 com.android.tools.r8.R8;
+import com.android.tools.r8.R8Command;
+import com.android.tools.r8.ToolHelper;
+import com.android.tools.r8.graph.DexEncodedMethod;
+import com.android.tools.r8.graph.JarCode;
+import com.android.tools.r8.origin.Origin;
+import com.android.tools.r8.utils.AndroidAppConsumers;
+import com.android.tools.r8.utils.DexInspector;
+import java.util.ArrayList;
+import java.util.Collections;
+import org.junit.Test;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.tree.AbstractInsnNode;
+import org.objectweb.asm.tree.InsnList;
+import org.objectweb.asm.tree.MethodNode;
+
+public class SynchronizedNoopTestRunner {
+  private byte[] data;
+  static final Class CLASS = SynchronizedNoopTest.class;
+
+  @Test
+  public void testSynchronizedNoop() throws Exception {
+    AndroidAppConsumers a = new AndroidAppConsumers();
+    R8.run(
+        R8Command.builder()
+            .addClassProgramData(ToolHelper.getClassAsBytes(CLASS), Origin.unknown())
+            .addLibraryFiles(ToolHelper.getAndroidJar(ToolHelper.getMinApiLevelForDexVm()))
+            .setProgramConsumer(a.wrapClassFileConsumer(null))
+            .build());
+    DexInspector inspector = new DexInspector(a.build());
+    DexEncodedMethod method =
+        inspector.clazz(CLASS).method("void", "noop", Collections.emptyList()).getMethod();
+    ArrayList<AbstractInsnNode> insns = new ArrayList<>();
+    JarCode jarCode = method.getCode().asJarCode();
+    MethodNode node = jarCode.getNode();
+    assert node != null;
+    InsnList asmInsns = node.instructions;
+    for (int i = 0; i < asmInsns.size(); i++) {
+      insns.add(asmInsns.get(i));
+    }
+    boolean hasMonitor =
+        insns
+            .stream()
+            .anyMatch(
+                insn ->
+                    insn.getOpcode() == Opcodes.MONITORENTER
+                        || insn.getOpcode() == Opcodes.MONITOREXIT);
+    // TODO(b/73921688): Should not have monitor instruction here
+    assert hasMonitor;
+  }
+}