Version 1.6.46

Cherry-pick: Don't run the outliner when compiling to classfiles.
CL: https://r8-review.googlesource.com/c/r8/+/45007

Resolved conflict by adding
src/test/java/com/android/tools/r8/ir/optimize/outliner/OutlinesWithNonNullTest.java
which was not on the branch.

Bug: 143550696
Change-Id: Ica63d398d8ecfe6c645332231e2dea5998dece73
diff --git a/src/main/java/com/android/tools/r8/R8Command.java b/src/main/java/com/android/tools/r8/R8Command.java
index 235882e..a568336 100644
--- a/src/main/java/com/android/tools/r8/R8Command.java
+++ b/src/main/java/com/android/tools/r8/R8Command.java
@@ -859,6 +859,13 @@
       internal.assertionProcessing = AssertionProcessing.LEAVE;
     }
 
+    // When generating class files the build is "intermediate" and we cannot pollute the namespace
+    // with the a hard-coded outline class. Doing so would prohibit subsequent merging of two
+    // R8 produced libraries.
+    if (internal.isGeneratingClassFiles()) {
+      internal.outline.enabled = false;
+    }
+
     // EXPERIMENTAL flags.
     assert !internal.forceProguardCompatibility;
     internal.forceProguardCompatibility = forceProguardCompatibility;
diff --git a/src/main/java/com/android/tools/r8/Version.java b/src/main/java/com/android/tools/r8/Version.java
index 05e7e22..091b934 100644
--- a/src/main/java/com/android/tools/r8/Version.java
+++ b/src/main/java/com/android/tools/r8/Version.java
@@ -11,7 +11,7 @@
 
   // This field is accessed from release scripts using simple pattern matching.
   // Therefore, changing this field could break our release scripts.
-  public static final String LABEL = "1.6.45";
+  public static final String LABEL = "1.6.46";
 
   private Version() {
   }
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/outliner/NoOutliningForClassFileBuildsTest.java b/src/test/java/com/android/tools/r8/ir/optimize/outliner/NoOutliningForClassFileBuildsTest.java
new file mode 100644
index 0000000..4af2593
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/ir/optimize/outliner/NoOutliningForClassFileBuildsTest.java
@@ -0,0 +1,102 @@
+// 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.outliner;
+
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertEquals;
+
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.utils.InternalOptions.OutlineOptions;
+import com.android.tools.r8.utils.StringUtils;
+import com.android.tools.r8.utils.codeinspector.ClassSubject;
+import com.android.tools.r8.utils.codeinspector.CodeInspector;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+@RunWith(Parameterized.class)
+public class NoOutliningForClassFileBuildsTest extends TestBase {
+
+  static final String EXPECTED = StringUtils.lines("foobarbaz");
+
+  private final TestParameters parameters;
+  private final boolean forceOutline;
+
+  @Parameterized.Parameters(name = "{0}, force-outline: {1}")
+  public static Collection<Object[]> data() {
+    List<Object[]> args = new ArrayList<>();
+    for (TestParameters parameter : getTestParameters().withAllRuntimesAndApiLevels().build()) {
+      args.add(new Object[] {parameter, false});
+      if (parameter.isCfRuntime()) {
+        args.add(new Object[] {parameter, true});
+      }
+    }
+    return args;
+  }
+
+  public NoOutliningForClassFileBuildsTest(TestParameters parameters, boolean forceOutline) {
+    this.parameters = parameters;
+    this.forceOutline = forceOutline;
+  }
+
+  @Test
+  public void test() throws Exception {
+    testForR8(parameters.getBackend())
+        .noMinification()
+        .addProgramClasses(TestClass.class)
+        .addKeepClassAndMembersRules(TestClass.class)
+        .setMinApi(parameters.getApiLevel())
+        .addOptionsModification(
+            o -> {
+              if (forceOutline) {
+                o.outline.enabled = true;
+              }
+              o.outline.minSize = 2;
+              o.outline.maxSize = 20;
+              o.outline.threshold = 2;
+            })
+        .run(parameters.getRuntime(), TestClass.class)
+        .assertSuccessWithOutput(EXPECTED)
+        .inspect(this::checkOutlining);
+  }
+
+  private void checkOutlining(CodeInspector inspector) {
+    ClassSubject classSubject = inspector.clazz(TestClass.class);
+    assertThat(classSubject, isPresent());
+    assertThat(classSubject.uniqueMethodWithName("foo"), isPresent());
+    assertThat(classSubject.uniqueMethodWithName("bar"), isPresent());
+    boolean hasOutlineClass =
+        inspector.allClasses().stream()
+            .anyMatch(c -> c.getFinalName().equals(OutlineOptions.CLASS_NAME));
+    assertEquals(forceOutline || parameters.isDexRuntime(), hasOutlineClass);
+  }
+
+  static class TestClass {
+
+    public void foo(String arg) {
+      StringBuilder builder = new StringBuilder();
+      builder.append("foo");
+      builder.append(arg);
+      builder.append("baz");
+      System.out.println(builder.toString());
+    }
+
+    public void bar(String arg) {
+      StringBuilder builder = new StringBuilder();
+      builder.append("foo");
+      builder.append(arg);
+      builder.append("baz");
+      System.out.println(builder.toString());
+    }
+
+    public static void main(String[] args) {
+      new TestClass().foo("bar");
+    }
+  }
+}
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/outliner/OutlinesWithNonNullTest.java b/src/test/java/com/android/tools/r8/ir/optimize/outliner/OutlinesWithNonNullTest.java
new file mode 100644
index 0000000..bea51f6
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/ir/optimize/outliner/OutlinesWithNonNullTest.java
@@ -0,0 +1,194 @@
+// 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.outliner;
+
+import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
+import static org.hamcrest.CoreMatchers.not;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import com.android.tools.r8.NeverClassInline;
+import com.android.tools.r8.NeverInline;
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.TestParametersCollection;
+import com.android.tools.r8.utils.InternalOptions.OutlineOptions;
+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.CodeMatchers;
+import com.android.tools.r8.utils.codeinspector.MethodSubject;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+@RunWith(Parameterized.class)
+public class OutlinesWithNonNullTest extends TestBase {
+  private static final String JVM_OUTPUT = StringUtils.lines(
+      "42",
+      "arg",
+      "42",
+      "arg"
+  );
+
+  private final TestParameters parameters;
+
+  @Parameterized.Parameters(name = "{0}")
+  public static TestParametersCollection data() {
+    return getTestParameters().withAllRuntimes().build();
+  }
+
+  public OutlinesWithNonNullTest(TestParameters parameters) {
+    this.parameters = parameters;
+  }
+
+  @Test
+  public void testNonNullOnOneSide() throws Exception {
+    testForR8(parameters.getBackend())
+        .enableClassInliningAnnotations()
+        .enableInliningAnnotations()
+        .addProgramClasses(TestArg.class, TestClassWithNonNullOnOneSide.class)
+        .addKeepMainRule(TestClassWithNonNullOnOneSide.class)
+        .setMinApi(parameters.getRuntime())
+        .allowAccessModification()
+        .noMinification()
+        .addOptionsModification(
+            options -> {
+              if (parameters.isCfRuntime()) {
+                assert !options.outline.enabled;
+                options.outline.enabled = true;
+              }
+              options.outline.threshold = 2;
+              options.outline.minSize = 2;
+            })
+        .compile()
+        .inspect(inspector -> validateOutlining(inspector, TestClassWithNonNullOnOneSide.class))
+        .run(parameters.getRuntime(), TestClassWithNonNullOnOneSide.class)
+        .assertSuccessWithOutput(JVM_OUTPUT);
+  }
+
+  @Test
+  public void testNonNullOnBothSides() throws Exception {
+    testForR8(parameters.getBackend())
+        .enableClassInliningAnnotations()
+        .enableInliningAnnotations()
+        .addProgramClasses(TestArg.class, TestClassWithNonNullOnBothSides.class)
+        .addKeepMainRule(TestClassWithNonNullOnBothSides.class)
+        .setMinApi(parameters.getRuntime())
+        .allowAccessModification()
+        .noMinification()
+        .addOptionsModification(
+            options -> {
+              if (parameters.isCfRuntime()) {
+                assert !options.outline.enabled;
+                options.outline.enabled = true;
+              }
+              options.outline.threshold = 2;
+              options.outline.minSize = 2;
+            })
+        .compile()
+        .inspect(inspector -> validateOutlining(inspector, TestClassWithNonNullOnBothSides.class))
+        .run(parameters.getRuntime(), TestClassWithNonNullOnBothSides.class)
+        .assertSuccessWithOutput(JVM_OUTPUT);
+  }
+
+  private void validateOutlining(CodeInspector inspector, Class<?> main) {
+    ClassSubject outlineClass = inspector.clazz(OutlineOptions.CLASS_NAME);
+    assertThat(outlineClass, isPresent());
+    MethodSubject outlineMethod = outlineClass.uniqueMethodWithName("outline0");
+    assertThat(outlineMethod, isPresent());
+
+    ClassSubject argClass = inspector.clazz(TestArg.class);
+    assertThat(argClass, isPresent());
+    MethodSubject printHash = argClass.uniqueMethodWithName("printHash");
+    assertThat(printHash, isPresent());
+    MethodSubject printArg= argClass.uniqueMethodWithName("printArg");
+    assertThat(printArg, isPresent());
+
+    ClassSubject classSubject = inspector.clazz(main);
+    assertThat(classSubject, isPresent());
+    MethodSubject method1 = classSubject.uniqueMethodWithName("method1");
+    assertThat(method1, isPresent());
+    assertThat(method1, CodeMatchers.invokesMethod(outlineMethod));
+    assertThat(method1, not(CodeMatchers.invokesMethod(printHash)));
+    assertThat(method1, not(CodeMatchers.invokesMethod(printArg)));
+    MethodSubject method2 = classSubject.uniqueMethodWithName("method2");
+    assertThat(method2, isPresent());
+    assertThat(method2, CodeMatchers.invokesMethod(outlineMethod));
+    assertThat(method2, not(CodeMatchers.invokesMethod(printHash)));
+    assertThat(method2, not(CodeMatchers.invokesMethod(printArg)));
+  }
+
+  @NeverClassInline
+  public static class TestArg {
+    @Override
+    public int hashCode() {
+      return 42;
+    }
+
+    @Override
+    public String toString() {
+      return "arg";
+    }
+
+    @NeverInline
+    static void printHash(Object arg) {
+      if (arg == null) {
+        throw new NullPointerException();
+      }
+      System.out.println(arg.hashCode());
+      // This method guarantees that, at the normal exit, argument is not null.
+    }
+
+    @NeverInline
+    static void printArg(Object arg) {
+      System.out.println(arg);
+    }
+  }
+
+  static class TestClassWithNonNullOnOneSide {
+    @NeverInline
+    static void method1(Object arg) {
+      TestArg.printHash(arg);
+      // We will have non-null aliasing here.
+      TestArg.printArg(arg);
+    }
+
+    @NeverInline
+    static void method2(Object arg) {
+      if (arg != null) {
+        // We will have non-null aliasing here.
+        TestArg.printHash(arg);
+        TestArg.printArg(arg);
+      }
+    }
+
+    public static void main(String... args) {
+      TestArg arg = new TestArg();
+      method1(arg);
+      method2(arg);
+    }
+  }
+
+  static class TestClassWithNonNullOnBothSides {
+    @NeverInline
+    static void method1(Object arg) {
+      TestArg.printHash(arg);
+      // We will have non-null aliasing here.
+      TestArg.printArg(arg);
+    }
+
+    @NeverInline
+    static void method2(Object arg) {
+      TestArg.printHash(arg);
+      // We will have non-null aliasing here.
+      TestArg.printArg(arg);
+    }
+
+    public static void main(String... args) {
+      TestArg arg = new TestArg();
+      method1(arg);
+      method2(arg);
+    }
+  }
+}
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/outliner/arraytypes/OutlinesWithClassArrayTypeArguments.java b/src/test/java/com/android/tools/r8/ir/optimize/outliner/arraytypes/OutlinesWithClassArrayTypeArguments.java
index 604e3fe..099afa8 100644
--- a/src/test/java/com/android/tools/r8/ir/optimize/outliner/arraytypes/OutlinesWithClassArrayTypeArguments.java
+++ b/src/test/java/com/android/tools/r8/ir/optimize/outliner/arraytypes/OutlinesWithClassArrayTypeArguments.java
@@ -63,6 +63,10 @@
         .noMinification()
         .addOptionsModification(
             options -> {
+              if (parameters.isCfRuntime()) {
+                assert !options.outline.enabled;
+                options.outline.enabled = true;
+              }
               options.outline.threshold = 2;
               options.outline.minSize = 2;
             })
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/outliner/arraytypes/OutlinesWithInterfaceArrayTypeArguments.java b/src/test/java/com/android/tools/r8/ir/optimize/outliner/arraytypes/OutlinesWithInterfaceArrayTypeArguments.java
index 33e5f96..fb4417f 100644
--- a/src/test/java/com/android/tools/r8/ir/optimize/outliner/arraytypes/OutlinesWithInterfaceArrayTypeArguments.java
+++ b/src/test/java/com/android/tools/r8/ir/optimize/outliner/arraytypes/OutlinesWithInterfaceArrayTypeArguments.java
@@ -74,6 +74,10 @@
         .noMinification()
         .addOptionsModification(
             options -> {
+              if (parameters.isCfRuntime()) {
+                assert !options.outline.enabled;
+                options.outline.enabled = true;
+              }
               options.outline.threshold = 2;
               options.outline.minSize = 2;
               options.testing.allowOutlinerInterfaceArrayArguments =
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/outliner/arraytypes/OutlinesWithPrimitiveArrayTypeArguments.java b/src/test/java/com/android/tools/r8/ir/optimize/outliner/arraytypes/OutlinesWithPrimitiveArrayTypeArguments.java
index 8a78d77..7a69926 100644
--- a/src/test/java/com/android/tools/r8/ir/optimize/outliner/arraytypes/OutlinesWithPrimitiveArrayTypeArguments.java
+++ b/src/test/java/com/android/tools/r8/ir/optimize/outliner/arraytypes/OutlinesWithPrimitiveArrayTypeArguments.java
@@ -59,6 +59,10 @@
         .noMinification()
         .addOptionsModification(
             options -> {
+              if (parameters.isCfRuntime()) {
+                assert !options.outline.enabled;
+                options.outline.enabled = true;
+              }
               options.outline.threshold = 2;
               options.outline.minSize = 2;
             })
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/outliner/b112247415/B112247415.java b/src/test/java/com/android/tools/r8/ir/optimize/outliner/b112247415/B112247415.java
index ef9e4f3..9fcc6b7 100644
--- a/src/test/java/com/android/tools/r8/ir/optimize/outliner/b112247415/B112247415.java
+++ b/src/test/java/com/android/tools/r8/ir/optimize/outliner/b112247415/B112247415.java
@@ -85,6 +85,10 @@
         .addProgramClassesAndInnerClasses(TestClass.class)
         .addKeepMainRule(TestClass.class)
         .addOptionsModification(options -> {
+          if (parameters.isCfRuntime()) {
+            assert !options.outline.enabled;
+            options.outline.enabled = true;
+          }
           // To trigger outliner, set # of expected outline candidate as threshold.
           options.outline.threshold = 2;
           options.enableInlining = false;
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/outliner/b133215941/B133215941.java b/src/test/java/com/android/tools/r8/ir/optimize/outliner/b133215941/B133215941.java
index c7d5cf0..b380f62 100644
--- a/src/test/java/com/android/tools/r8/ir/optimize/outliner/b133215941/B133215941.java
+++ b/src/test/java/com/android/tools/r8/ir/optimize/outliner/b133215941/B133215941.java
@@ -70,7 +70,13 @@
         .addKeepClassAndMembersRules(ClassWithStaticMethod.class)
         .setMinApi(parameters.getRuntime())
         .noMinification()
-        .addOptionsModification(options -> options.outline.threshold = 2)
+        .addOptionsModification(options -> {
+          if (parameters.isCfRuntime()) {
+            assert !options.outline.enabled;
+            options.outline.enabled = true;
+          }
+          options.outline.threshold = 2;
+        })
         .compile()
         .inspect(this::validateOutlining)
         .run(parameters.getRuntime(), TestClass.class)
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/outliner/classtypes/B134462736.java b/src/test/java/com/android/tools/r8/ir/optimize/outliner/classtypes/B134462736.java
index 177bc91..eab6811 100644
--- a/src/test/java/com/android/tools/r8/ir/optimize/outliner/classtypes/B134462736.java
+++ b/src/test/java/com/android/tools/r8/ir/optimize/outliner/classtypes/B134462736.java
@@ -67,6 +67,10 @@
         .noMinification()
         .addOptionsModification(
             options -> {
+              if (parameters.isCfRuntime()) {
+                assert !options.outline.enabled;
+                options.outline.enabled = true;
+              }
               options.outline.threshold = 2;
               options.outline.minSize = 2;
             })
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/outliner/primitivetypes/PrimitiveTypesTest.java b/src/test/java/com/android/tools/r8/ir/optimize/outliner/primitivetypes/PrimitiveTypesTest.java
index aba1f31..f6e72b2 100644
--- a/src/test/java/com/android/tools/r8/ir/optimize/outliner/primitivetypes/PrimitiveTypesTest.java
+++ b/src/test/java/com/android/tools/r8/ir/optimize/outliner/primitivetypes/PrimitiveTypesTest.java
@@ -62,6 +62,10 @@
         .noMinification()
         .addOptionsModification(
             options -> {
+              if (parameters.isCfRuntime()) {
+                assert !options.outline.enabled;
+                options.outline.enabled = true;
+              }
               options.outline.threshold = 2;
               options.outline.minSize = 2;
             })