Enable unused argument removal for non-private constructors

Bug: 123004864, 122683370
Change-Id: I4e576c2c9f90fd64fbf35731b06099c639be4a52
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/UnusedArgumentsCollector.java b/src/main/java/com/android/tools/r8/ir/optimize/UnusedArgumentsCollector.java
index 9d2bb32..061907f 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/UnusedArgumentsCollector.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/UnusedArgumentsCollector.java
@@ -211,7 +211,9 @@
     int argumentCount =
         method.method.proto.parameters.size() + (method.accessFlags.isStatic() ? 0 : 1);
     // TODO(65810338): Implement for virtual methods as well.
-    if (method.accessFlags.isPrivate() || method.accessFlags.isStatic()) {
+    if (method.accessFlags.isPrivate()
+        || method.accessFlags.isStatic()
+        || method.isInstanceInitializer()) {
       CollectUsedArguments collector = new CollectUsedArguments();
       if (!method.accessFlags.isStatic()) {
         // TODO(65810338): The receiver cannot be removed without transforming the method to being
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/unusedarguments/UnusedArgumentsInstanceConstructorTest.java b/src/test/java/com/android/tools/r8/ir/optimize/unusedarguments/UnusedArgumentsInstanceConstructorTest.java
new file mode 100644
index 0000000..20d7bae
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/ir/optimize/unusedarguments/UnusedArgumentsInstanceConstructorTest.java
@@ -0,0 +1,95 @@
+// Copyright (c) 2019, 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.ir.optimize.unusedarguments;
+
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
+import static org.hamcrest.CoreMatchers.not;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+
+import com.android.tools.r8.NeverClassInline;
+import com.android.tools.r8.NeverInline;
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.utils.StringUtils;
+import com.android.tools.r8.utils.codeinspector.ClassSubject;
+import com.android.tools.r8.utils.codeinspector.CodeInspector;
+import com.android.tools.r8.utils.codeinspector.MethodSubject;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+@RunWith(Parameterized.class)
+public class UnusedArgumentsInstanceConstructorTest extends TestBase {
+
+  private final Backend backend;
+
+  @Parameters(name = "Backend: {0}")
+  public static Backend[] data() {
+    return Backend.values();
+  }
+
+  public UnusedArgumentsInstanceConstructorTest(Backend backend) {
+    this.backend = backend;
+  }
+
+  @Test
+  public void test() throws Exception {
+    String expectedOutput = StringUtils.lines("Hello world");
+
+    if (backend == Backend.CF) {
+      testForJvm().addTestClasspath().run(TestClass.class).assertSuccessWithOutput(expectedOutput);
+    }
+
+    CodeInspector inspector =
+        testForR8(backend)
+            .addInnerClasses(UnusedArgumentsInstanceConstructorTest.class)
+            .addKeepMainRule(TestClass.class)
+            .enableInliningAnnotations()
+            .enableClassInliningAnnotations()
+            .run(TestClass.class)
+            .assertSuccessWithOutput(expectedOutput)
+            .inspector();
+
+    ClassSubject classSubject = inspector.clazz(A.class);
+    assertThat(classSubject, isPresent());
+
+    MethodSubject methodSubject = classSubject.uniqueMethodWithName("<init>");
+    assertThat(methodSubject, isPresent());
+    assertTrue(methodSubject.getMethod().method.proto.parameters.isEmpty());
+
+    assertThat(inspector.clazz(B.class), not(isPresent()));
+    assertThat(inspector.clazz(C.class), not(isPresent()));
+  }
+
+  static class TestClass {
+
+    public static void main(String[] args) {
+      new A(null, new C()).doSomething();
+    }
+  }
+
+  @NeverClassInline
+  static class A {
+
+    public A(B uninstantiated, C unused) {
+      System.out.print("Hello");
+      if (uninstantiated != null) {
+        throw new RuntimeException("Unreachable");
+      } else {
+        System.out.print(" ");
+      }
+    }
+
+    @NeverInline
+    public void doSomething() {
+      System.out.println("world");
+    }
+  }
+
+  static class B {}
+
+  static class C {}
+}