Add failing test for class inliner bug
Bug: 120182628
Change-Id: I28fec0cdfe3ed86ac3390e276f786034eb586f84
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/classinliner/ClassInliner.java b/src/main/java/com/android/tools/r8/ir/optimize/classinliner/ClassInliner.java
index eb42723..03dd7f2 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/classinliner/ClassInliner.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/classinliner/ClassInliner.java
@@ -128,9 +128,10 @@
Supplier<InliningOracle> defaultOracle) {
// Collect all the new-instance and static-get instructions in the code before inlining.
- List<Instruction> roots = Streams.stream(code.instructionIterator())
- .filter(insn -> insn.isNewInstance() || insn.isStaticGet())
- .collect(Collectors.toList());
+ List<Instruction> roots =
+ Streams.stream(code.instructionIterator())
+ .filter(insn -> insn.isNewInstance() || insn.isStaticGet())
+ .collect(Collectors.toList());
// We loop inlining iterations until there was no inlining, but still use same set
// of roots to avoid infinite inlining. Looping makes possible for some roots to
@@ -153,7 +154,6 @@
if (!processor.isInstanceEligible() ||
!processor.isClassAndUsageEligible()) {
// This root will never be inlined.
- rootsIterator.remove();
continue;
}
@@ -174,7 +174,6 @@
// Restore normality.
code.removeAllTrivialPhis();
assert code.isConsistentSSA();
- rootsIterator.remove();
repeat = true;
}
} while (repeat);
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/classinliner/InlineCandidateProcessor.java b/src/main/java/com/android/tools/r8/ir/optimize/classinliner/InlineCandidateProcessor.java
index 7754a14..d952a6c 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/classinliner/InlineCandidateProcessor.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/classinliner/InlineCandidateProcessor.java
@@ -104,8 +104,8 @@
return false;
}
- eligibleClass = isNewInstance() ?
- root.asNewInstance().clazz : root.asStaticGet().getField().type;
+ eligibleClass =
+ root.isNewInstance() ? root.asNewInstance().clazz : root.asStaticGet().getField().type;
eligibleClassDefinition = appInfo.definitionFor(eligibleClass);
if (eligibleClassDefinition == null && lambdaRewriter != null) {
// Check if the class is synthesized for a desugared lambda
@@ -131,7 +131,7 @@
return false;
}
- if (isNewInstance()) {
+ if (root.isNewInstance()) {
// NOTE: if the eligible class does not directly extend java.lang.Object,
// we also have to guarantee that it is initialized with initializer classified as
// TrivialInstanceInitializer. This will be checked in areInstanceUsersEligible(...).
@@ -799,10 +799,6 @@
}
}
- private boolean isNewInstance() {
- return root.isNewInstance();
- }
-
private DexEncodedMethod findSingleTarget(DexMethod callee, boolean isDirect) {
// We don't use computeSingleTarget(...) on invoke since it sometimes fails to
// find the single target, while this code may be more successful since we exactly
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/classinliner/BuilderWithSelfReferenceTest.java b/src/test/java/com/android/tools/r8/ir/optimize/classinliner/BuilderWithSelfReferenceTest.java
new file mode 100644
index 0000000..06659a6
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/ir/optimize/classinliner/BuilderWithSelfReferenceTest.java
@@ -0,0 +1,44 @@
+// 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.ir.optimize.classinliner;
+
+import com.android.tools.r8.NeverInline;
+import com.android.tools.r8.TestBase;
+import org.junit.Ignore;
+import org.junit.Test;
+
+/** Regression test for b/120182628. */
+public class BuilderWithSelfReferenceTest extends TestBase {
+
+ @Test
+ @Ignore("b/120182628")
+ public void test() throws Exception {
+ testForR8(Backend.DEX)
+ .addInnerClasses(BuilderWithSelfReferenceTest.class)
+ .addKeepMainRule(TestClass.class)
+ .enableInliningAnnotations()
+ .compile();
+ }
+
+ static class TestClass {
+
+ public static void main(String[] args) {
+ new Builder().build();
+ }
+ }
+
+ static class Builder {
+
+ public Builder f = this;
+
+ public Object build() {
+ invoke(f);
+ return new Object();
+ }
+
+ @NeverInline
+ public static void invoke(Object o) {}
+ }
+}