Disallow simplifying arrays to interface types if not exact type match
Bug: b/283715197
Change-Id: Ie11bc1f834f3e30d23ae584ade0e006241e4b54b
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/passes/ArrayConstructionSimplifier.java b/src/main/java/com/android/tools/r8/ir/conversion/passes/ArrayConstructionSimplifier.java
index d6c709b..3176d29 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/passes/ArrayConstructionSimplifier.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/passes/ArrayConstructionSimplifier.java
@@ -430,7 +430,7 @@
if (clazz == null) {
return false;
}
- return clazz.isInterface() || valueType.isClassType(elementType);
+ return valueType.isClassType(elementType);
}
private boolean canUseFilledNewArray(DexType arrayType, int size, RewriteArrayOptions options) {
diff --git a/src/test/java/com/android/tools/r8/rewrite/arrays/SimplifyArrayConstructionTest.java b/src/test/java/com/android/tools/r8/rewrite/arrays/SimplifyArrayConstructionTest.java
index 76fcda9..9f67d23 100644
--- a/src/test/java/com/android/tools/r8/rewrite/arrays/SimplifyArrayConstructionTest.java
+++ b/src/test/java/com/android/tools/r8/rewrite/arrays/SimplifyArrayConstructionTest.java
@@ -228,22 +228,24 @@
assertArrayTypes(twoDimensionalArrays, DexNewArray.class);
assertArrayTypes(assumedValues, DexNewArray.class);
} else {
- assertArrayTypes(referenceArraysNoCasts, DexFilledNewArray.class);
+ if (parameters.canUseSubTypesInFilledNewArray()) {
+ assertArrayTypes(referenceArraysNoCasts, DexFilledNewArray.class);
+ } else {
+ assertArrayTypes(referenceArraysNoCasts, DexNewArray.class, DexFilledNewArray.class);
+ }
if (isR8 && parameters.canUseSubTypesInFilledNewArray()) {
assertArrayTypes(referenceArraysWithSubclasses, DexFilledNewArray.class);
- } else {
- assertArrayTypes(referenceArraysWithSubclasses, DexNewArray.class);
- }
- if (isR8) {
assertArrayTypes(referenceArraysWithInterfaceImplementations, DexFilledNewArray.class);
} else {
+ assertArrayTypes(referenceArraysWithSubclasses, DexNewArray.class);
assertArrayTypes(referenceArraysWithInterfaceImplementations, DexNewArray.class);
}
// TODO(b/246971330): Add support for arrays whose values have conditionals.
// assertArrayTypes(phiFilledNewArray, DexFilledNewArray.class);
- assertArrayTypes(objectArraysFilledNewArrayRange, DexFilledNewArrayRange.class);
+ assertArrayTypes(
+ objectArraysFilledNewArrayRange, DexFilledNewArrayRange.class, DexNewArray.class);
if (parameters.getApiLevel().isGreaterThanOrEqualTo(AndroidApiLevel.L)) {
assertArrayTypes(twoDimensionalArrays, DexFilledNewArray.class);
@@ -274,12 +276,14 @@
return isInstruction(Arrays.asList(clazz));
}
- private static void assertArrayTypes(MethodSubject method, Class<?> allowedArrayInst) {
+ private static void assertArrayTypes(MethodSubject method, Class<?>... allowedArrayInst) {
assertTrue(method.isPresent());
List<Class<?>> disallowedClasses = Lists.newArrayList(DEX_ARRAY_INSTRUCTIONS);
- disallowedClasses.remove(allowedArrayInst);
-
- assertTrue(method.streamInstructions().anyMatch(isInstruction(allowedArrayInst)));
+ for (Class<?> allowedArr : allowedArrayInst) {
+ disallowedClasses.remove(allowedArr);
+ }
+ assertTrue(
+ method.streamInstructions().anyMatch(isInstruction(Arrays.asList(allowedArrayInst))));
assertTrue(method.streamInstructions().noneMatch(isInstruction(disallowedClasses)));
}