Account for dynamic null receiver type in argument propagation

Bug: b/250634405
Change-Id: I4d29c793951f11189ae7954380d72a3b056027f3
diff --git a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagatorCodeScanner.java b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagatorCodeScanner.java
index eff76c7..9023c00 100644
--- a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagatorCodeScanner.java
+++ b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagatorCodeScanner.java
@@ -284,7 +284,13 @@
       ProgramMethod context,
       ConcretePolymorphicMethodStateOrBottom existingMethodState) {
     DynamicTypeWithUpperBound dynamicReceiverType = invoke.getReceiver().getDynamicType(appView);
-    assert !dynamicReceiverType.getDynamicUpperBoundType().nullability().isDefinitelyNull();
+    if (dynamicReceiverType.isNullType()) {
+      // This can happen if we were unable to determine that the receiver is a phi value where null
+      // information has not been propagated down. See if we can improve the test here or ensure
+      // that all phi's are normalized before computing the optimization info.
+      assert appView.checkForTesting(() -> false) : "b/250634405";
+      return MethodState.unknown();
+    }
 
     ProgramMethod singleTarget = invoke.lookupSingleProgramTarget(appView, context);
     DynamicTypeWithUpperBound bounds =
diff --git a/src/test/java/com/android/tools/r8/optimize/argumentpropagation/PolymorphicMethodWithNullReceiverBoundTest.java b/src/test/java/com/android/tools/r8/optimize/argumentpropagation/PolymorphicMethodWithNullReceiverBoundTest.java
index 5b09e47..5ad2a81 100644
--- a/src/test/java/com/android/tools/r8/optimize/argumentpropagation/PolymorphicMethodWithNullReceiverBoundTest.java
+++ b/src/test/java/com/android/tools/r8/optimize/argumentpropagation/PolymorphicMethodWithNullReceiverBoundTest.java
@@ -4,6 +4,7 @@
 
 package com.android.tools.r8.optimize.argumentpropagation;
 
+import static org.hamcrest.CoreMatchers.containsString;
 import static org.junit.Assert.assertThrows;
 
 import com.android.tools.r8.CompilationFailedException;
@@ -40,24 +41,45 @@
   }
 
   @Test
-  public void test() throws Exception {
-    // TODO(b/250634405): Check for null in dynamic receiver type.
+  public void testR8WithTestAssertionsEnabled() {
     assertThrows(
         CompilationFailedException.class,
-        () ->
-            testForR8(parameters.getBackend())
-                .addInnerClasses(getClass())
-                .addKeepMainRule(Main.class)
-                .enableNoHorizontalClassMergingAnnotations()
-                .enableNoVerticalClassMergingAnnotations()
-                .setMinApi(parameters.getApiLevel())
-                .addOptionsModification(
-                    options -> {
-                      options.testing.cfByteCodePassThrough =
-                          method -> method.getName().startsWith("main");
-                      options.testing.checkReceiverAlwaysNullInCallSiteOptimization = false;
-                    })
-                .compile());
+        () -> {
+          testForR8(parameters.getBackend())
+              .addInnerClasses(getClass())
+              .addKeepMainRule(Main.class)
+              .enableNoHorizontalClassMergingAnnotations()
+              .enableNoVerticalClassMergingAnnotations()
+              .setMinApi(parameters.getApiLevel())
+              .addOptionsModification(
+                  options -> {
+                    options.testing.cfByteCodePassThrough =
+                        method -> method.getName().startsWith("main");
+                    options.testing.checkReceiverAlwaysNullInCallSiteOptimization = false;
+                  })
+              .compileWithExpectedDiagnostics(
+                  diagnostics -> {
+                    diagnostics.assertErrorMessageThatMatches(containsString("b/250634405"));
+                  });
+        });
+  }
+
+  @Test
+  public void testR8WithoutTestAssertions() throws Exception {
+    testForR8(parameters.getBackend())
+        .addInnerClasses(getClass())
+        .addKeepMainRule(Main.class)
+        .enableNoHorizontalClassMergingAnnotations()
+        .enableNoVerticalClassMergingAnnotations()
+        .setMinApi(parameters.getApiLevel())
+        .addOptionsModification(
+            options -> {
+              options.testing.cfByteCodePassThrough = method -> method.getName().startsWith("main");
+              options.testing.checkReceiverAlwaysNullInCallSiteOptimization = false;
+              options.testing.enableTestAssertions = false;
+            })
+        .run(parameters.getRuntime(), Main.class)
+        .assertFailureWithErrorThatThrows(NullPointerException.class);
   }
 
   static class Main {