Version 1.0.31
Merge: Fix an infinite loop in CodeRewriter#simplifyArrayConstruction.
CL: https://r8-review.googlesource.com/c/r8/+/21880
Bug: 87341268
Change-Id: Ibccf02e65171eec8c4aa1c513fe0f65f11f23311
diff --git a/src/main/java/com/android/tools/r8/Version.java b/src/main/java/com/android/tools/r8/Version.java
index fb1837e..5c7bd78 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 = "v1.0.30";
+ public static final String LABEL = "v1.0.31";
private Version() {
}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/CodeRewriter.java b/src/main/java/com/android/tools/r8/ir/optimize/CodeRewriter.java
index 61cd3e7..4d745b4 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/CodeRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/CodeRewriter.java
@@ -1376,10 +1376,8 @@
return values;
}
}
- block =
- block.exit().isGoto() && !visitedBlocks.contains(block.exit().asGoto().getTarget())
- ? block.exit().asGoto().getTarget()
- : null;
+ BasicBlock nextBlock = block.exit().isGoto() ? block.exit().asGoto().getTarget() : null;
+ block = nextBlock != null && !visitedBlocks.contains(nextBlock) ? nextBlock : null;
it = block != null ? block.listIterator() : null;
} while (it != null);
return null;
@@ -1470,7 +1468,9 @@
// Second pass: remove all the array put instructions for the array for which we have
// inserted a fill array data instruction instead.
if (!storesToRemoveForArray.isEmpty()) {
+ Set<BasicBlock> visitedBlocks = Sets.newIdentityHashSet();
do {
+ visitedBlocks.add(block);
it = block.listIterator();
while (it.hasNext()) {
Instruction instruction = it.next();
@@ -1492,7 +1492,8 @@
}
}
}
- block = block.exit().isGoto() ? block.exit().asGoto().getTarget() : null;
+ BasicBlock nextBlock = block.exit().isGoto() ? block.exit().asGoto().getTarget() : null;
+ block = nextBlock != null && !visitedBlocks.contains(nextBlock) ? nextBlock : null;
} while (block != null);
}
}
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/B87341268.java b/src/test/java/com/android/tools/r8/ir/optimize/B87341268.java
new file mode 100644
index 0000000..f197f46
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/ir/optimize/B87341268.java
@@ -0,0 +1,38 @@
+// 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;
+
+import static org.junit.Assert.assertTrue;
+
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.utils.AndroidApp;
+import com.android.tools.r8.utils.DexInspector;
+import com.android.tools.r8.utils.DexInspector.ClassSubject;
+import org.junit.Test;
+
+public class B87341268 extends TestBase {
+ @Test
+ public void test() throws Exception {
+ AndroidApp app = compileWithD8(readClasses(TestClass.class));
+ DexInspector inspector = new DexInspector(app);
+ ClassSubject clazz = inspector.clazz(TestClass.class);
+ assertTrue(clazz.isPresent());
+ }
+}
+
+class TestClass {
+ int loop(String arg) {
+ long[] array = { 0L, 1L, 2L };
+ int length = -1;
+ while (true) {
+ try {
+ length = arg.length();
+ } catch (Exception e) {
+ System.err.println(e.getMessage());
+ break;
+ }
+ }
+ return length;
+ }
+}