Fix NumberUnboxer and virtual methods

Bug: b/307872552
Change-Id: I907a02ddf422c15269f2873598b637295a4e8472
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/numberunboxer/NumberUnboxerImpl.java b/src/main/java/com/android/tools/r8/ir/optimize/numberunboxer/NumberUnboxerImpl.java
index 1e623e1..b171360 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/numberunboxer/NumberUnboxerImpl.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/numberunboxer/NumberUnboxerImpl.java
@@ -26,6 +26,7 @@
 import com.android.tools.r8.ir.optimize.numberunboxer.TransitiveDependency.MethodRet;
 import com.android.tools.r8.optimize.argumentpropagation.utils.ProgramClassesBidirectedGraph;
 import com.android.tools.r8.shaking.AppInfoWithLiveness;
+import com.android.tools.r8.utils.BooleanUtils;
 import com.android.tools.r8.utils.MapUtils;
 import com.android.tools.r8.utils.ThreadUtils;
 import com.android.tools.r8.utils.Timing;
@@ -142,6 +143,7 @@
     DexMethod contextReference = code.context().getReference();
     ValueBoxingStatus[] args = null;
     ValueBoxingStatus returnStatus = null;
+    int shift = BooleanUtils.intValue(!code.context().getDefinition().isStatic());
     for (Instruction next : code.instructions()) {
       if (next.isArgument()) {
         ValueBoxingStatus unboxingStatus = analyzeOutput(next.outValue());
@@ -149,7 +151,7 @@
           if (args == null) {
             args = new ValueBoxingStatus[contextReference.getArity()];
           }
-          args[next.asArgument().getIndex()] = unboxingStatus;
+          args[next.asArgument().getIndex() - shift] = unboxingStatus;
         }
       } else if (next.isReturn()) {
         Return ret = next.asReturn();
@@ -223,8 +225,9 @@
     if (!inValue.isPhi()) {
       Instruction definition = inValue.getAliasedValue().getDefinition();
       if (definition.isArgument()) {
+        int shift = BooleanUtils.intValue(!context.getDefinition().isStatic());
         return ValueBoxingStatus.with(
-            new MethodArg(definition.asArgument().getIndex(), context.getReference()));
+            new MethodArg(definition.asArgument().getIndex() - shift, context.getReference()));
       }
       if (definition.isInvokeMethod()) {
         if (boxPrimitiveMethod.isIdenticalTo(definition.asInvokeMethod().getInvokedMethod())) {
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/numberunboxer/TransitiveDependency.java b/src/main/java/com/android/tools/r8/ir/optimize/numberunboxer/TransitiveDependency.java
index f368e52..ff49fe2 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/numberunboxer/TransitiveDependency.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/numberunboxer/TransitiveDependency.java
@@ -113,6 +113,7 @@
     public MethodArg(int parameterIndex, DexMethod method) {
       super(method);
       assert parameterIndex >= 0;
+      assert parameterIndex < method.getArity();
       this.parameterIndex = parameterIndex;
     }
 
diff --git a/src/test/java/com/android/tools/r8/numberunboxing/SimpleNumberUnboxingTest.java b/src/test/java/com/android/tools/r8/numberunboxing/StaticMethodsNumberUnboxingTest.java
similarity index 73%
rename from src/test/java/com/android/tools/r8/numberunboxing/SimpleNumberUnboxingTest.java
rename to src/test/java/com/android/tools/r8/numberunboxing/StaticMethodsNumberUnboxingTest.java
index ceaf904..61a658a 100644
--- a/src/test/java/com/android/tools/r8/numberunboxing/SimpleNumberUnboxingTest.java
+++ b/src/test/java/com/android/tools/r8/numberunboxing/StaticMethodsNumberUnboxingTest.java
@@ -16,14 +16,13 @@
 import com.android.tools.r8.utils.codeinspector.CodeInspector;
 import com.android.tools.r8.utils.codeinspector.MethodSubject;
 import java.util.Objects;
-import org.hamcrest.CoreMatchers;
 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 SimpleNumberUnboxingTest extends TestBase {
+public class StaticMethodsNumberUnboxingTest extends TestBase {
 
   private final TestParameters parameters;
 
@@ -32,7 +31,7 @@
     return getTestParameters().withAllRuntimesAndApiLevels().build();
   }
 
-  public SimpleNumberUnboxingTest(TestParameters parameters) {
+  public StaticMethodsNumberUnboxingTest(TestParameters parameters) {
     this.parameters = parameters;
   }
 
@@ -45,33 +44,8 @@
         .addOptionsModification(opt -> opt.testing.enableNumberUnboxer = true)
         .addOptionsModification(opt -> opt.testing.printNumberUnboxed = true)
         .setMinApi(parameters)
-        .allowDiagnosticWarningMessages()
         .compile()
         .inspect(this::assertUnboxing)
-        .assertWarningMessageThatMatches(
-            CoreMatchers.containsString(
-                "Unboxing of arg 0 of void"
-                    + " com.android.tools.r8.numberunboxing.SimpleNumberUnboxingTest$Main.print(java.lang.Integer)"))
-        .assertWarningMessageThatMatches(
-            CoreMatchers.containsString(
-                "Unboxing of arg 0 of void"
-                    + " com.android.tools.r8.numberunboxing.SimpleNumberUnboxingTest$Main.forwardToPrint2(java.lang.Integer)"))
-        .assertWarningMessageThatMatches(
-            CoreMatchers.containsString(
-                "Unboxing of arg 0 of void"
-                    + " com.android.tools.r8.numberunboxing.SimpleNumberUnboxingTest$Main.directPrintUnbox(java.lang.Integer)"))
-        .assertWarningMessageThatMatches(
-            CoreMatchers.containsString(
-                "Unboxing of arg 0 of void"
-                    + " com.android.tools.r8.numberunboxing.SimpleNumberUnboxingTest$Main.forwardToPrint(java.lang.Integer)"))
-        .assertWarningMessageThatMatches(
-            CoreMatchers.containsString(
-                "Unboxing of return value of java.lang.Integer"
-                    + " com.android.tools.r8.numberunboxing.SimpleNumberUnboxingTest$Main.get()"))
-        .assertWarningMessageThatMatches(
-            CoreMatchers.containsString(
-                "Unboxing of return value of java.lang.Integer"
-                    + " com.android.tools.r8.numberunboxing.SimpleNumberUnboxingTest$Main.forwardGet()"))
         .run(parameters.getRuntime(), Main.class)
         .assertSuccessWithOutputLines("32", "33", "42", "43", "51", "52", "2");
   }
diff --git a/src/test/java/com/android/tools/r8/numberunboxing/SimpleNumberUnboxingTest.java b/src/test/java/com/android/tools/r8/numberunboxing/VirtualMethodsNumberUnboxingTest.java
similarity index 63%
copy from src/test/java/com/android/tools/r8/numberunboxing/SimpleNumberUnboxingTest.java
copy to src/test/java/com/android/tools/r8/numberunboxing/VirtualMethodsNumberUnboxingTest.java
index ceaf904..d902229 100644
--- a/src/test/java/com/android/tools/r8/numberunboxing/SimpleNumberUnboxingTest.java
+++ b/src/test/java/com/android/tools/r8/numberunboxing/VirtualMethodsNumberUnboxingTest.java
@@ -16,14 +16,13 @@
 import com.android.tools.r8.utils.codeinspector.CodeInspector;
 import com.android.tools.r8.utils.codeinspector.MethodSubject;
 import java.util.Objects;
-import org.hamcrest.CoreMatchers;
 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 SimpleNumberUnboxingTest extends TestBase {
+public class VirtualMethodsNumberUnboxingTest extends TestBase {
 
   private final TestParameters parameters;
 
@@ -32,7 +31,7 @@
     return getTestParameters().withAllRuntimesAndApiLevels().build();
   }
 
-  public SimpleNumberUnboxingTest(TestParameters parameters) {
+  public VirtualMethodsNumberUnboxingTest(TestParameters parameters) {
     this.parameters = parameters;
   }
 
@@ -43,35 +42,9 @@
         .addKeepMainRule(Main.class)
         .enableInliningAnnotations()
         .addOptionsModification(opt -> opt.testing.enableNumberUnboxer = true)
-        .addOptionsModification(opt -> opt.testing.printNumberUnboxed = true)
         .setMinApi(parameters)
-        .allowDiagnosticWarningMessages()
         .compile()
         .inspect(this::assertUnboxing)
-        .assertWarningMessageThatMatches(
-            CoreMatchers.containsString(
-                "Unboxing of arg 0 of void"
-                    + " com.android.tools.r8.numberunboxing.SimpleNumberUnboxingTest$Main.print(java.lang.Integer)"))
-        .assertWarningMessageThatMatches(
-            CoreMatchers.containsString(
-                "Unboxing of arg 0 of void"
-                    + " com.android.tools.r8.numberunboxing.SimpleNumberUnboxingTest$Main.forwardToPrint2(java.lang.Integer)"))
-        .assertWarningMessageThatMatches(
-            CoreMatchers.containsString(
-                "Unboxing of arg 0 of void"
-                    + " com.android.tools.r8.numberunboxing.SimpleNumberUnboxingTest$Main.directPrintUnbox(java.lang.Integer)"))
-        .assertWarningMessageThatMatches(
-            CoreMatchers.containsString(
-                "Unboxing of arg 0 of void"
-                    + " com.android.tools.r8.numberunboxing.SimpleNumberUnboxingTest$Main.forwardToPrint(java.lang.Integer)"))
-        .assertWarningMessageThatMatches(
-            CoreMatchers.containsString(
-                "Unboxing of return value of java.lang.Integer"
-                    + " com.android.tools.r8.numberunboxing.SimpleNumberUnboxingTest$Main.get()"))
-        .assertWarningMessageThatMatches(
-            CoreMatchers.containsString(
-                "Unboxing of return value of java.lang.Integer"
-                    + " com.android.tools.r8.numberunboxing.SimpleNumberUnboxingTest$Main.forwardGet()"))
         .run(parameters.getRuntime(), Main.class)
         .assertSuccessWithOutputLines("32", "33", "42", "43", "51", "52", "2");
   }
@@ -105,59 +78,62 @@
 
   static class Main {
 
+    private static final Main MAIN = new Main();
+
     public static void main(String[] args) {
+
       // The number unboxer should immediately find this method is worth unboxing.
-      directPrintUnbox(31);
-      directPrintUnbox(32);
+      MAIN.directPrintUnbox(31);
+      MAIN.directPrintUnbox(32);
 
       // The number unboxer should find the chain of calls is worth unboxing.
-      forwardToPrint(41);
-      forwardToPrint(42);
+      MAIN.forwardToPrint(41);
+      MAIN.forwardToPrint(42);
 
       // The number unboxer should find this method is *not* worth unboxing.
       Integer decode1 = Integer.decode("51");
       Objects.requireNonNull(decode1);
-      directPrintNotUnbox(decode1);
+      MAIN.directPrintNotUnbox(decode1);
       Integer decode2 = Integer.decode("52");
       Objects.requireNonNull(decode2);
-      directPrintNotUnbox(decode2);
+      MAIN.directPrintNotUnbox(decode2);
 
       // The number unboxer should unbox the return values.
-      System.out.println(forwardGet() + 1);
+      System.out.println(MAIN.forwardGet() + 1);
     }
 
     @NeverInline
-    private static Integer get() {
+    public Integer get() {
       return System.currentTimeMillis() > 0 ? 1 : -1;
     }
 
     @NeverInline
-    private static Integer forwardGet() {
+    public Integer forwardGet() {
       return get();
     }
 
     @NeverInline
-    private static void forwardToPrint(Integer boxed) {
+    public void forwardToPrint(Integer boxed) {
       forwardToPrint2(boxed);
     }
 
     @NeverInline
-    private static void forwardToPrint2(Integer boxed) {
+    public void forwardToPrint2(Integer boxed) {
       print(boxed);
     }
 
     @NeverInline
-    private static void print(Integer boxed) {
+    public void print(Integer boxed) {
       System.out.println(boxed + 1);
     }
 
     @NeverInline
-    private static void directPrintUnbox(Integer boxed) {
+    public void directPrintUnbox(Integer boxed) {
       System.out.println(boxed + 1);
     }
 
     @NeverInline
-    private static void directPrintNotUnbox(Integer boxed) {
+    public void directPrintNotUnbox(Integer boxed) {
       System.out.println(boxed);
     }
   }