Fix missing enum unboxing analysis of instance-of
Bug: b/321689478
Change-Id: Ib9a76e91543bb695c1033ebc648ee26b4f14be48
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/enums/EnumUnboxerImpl.java b/src/main/java/com/android/tools/r8/ir/optimize/enums/EnumUnboxerImpl.java
index 373c579..c570ab9 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/enums/EnumUnboxerImpl.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/enums/EnumUnboxerImpl.java
@@ -14,6 +14,7 @@
import static com.android.tools.r8.ir.code.Opcodes.IF;
import static com.android.tools.r8.ir.code.Opcodes.INIT_CLASS;
import static com.android.tools.r8.ir.code.Opcodes.INSTANCE_GET;
+import static com.android.tools.r8.ir.code.Opcodes.INSTANCE_OF;
import static com.android.tools.r8.ir.code.Opcodes.INSTANCE_PUT;
import static com.android.tools.r8.ir.code.Opcodes.INVOKE_CUSTOM;
import static com.android.tools.r8.ir.code.Opcodes.INVOKE_DIRECT;
@@ -68,6 +69,7 @@
import com.android.tools.r8.ir.code.IfType;
import com.android.tools.r8.ir.code.InitClass;
import com.android.tools.r8.ir.code.InstanceGet;
+import com.android.tools.r8.ir.code.InstanceOf;
import com.android.tools.r8.ir.code.Instruction;
import com.android.tools.r8.ir.code.InvokeCustom;
import com.android.tools.r8.ir.code.InvokeMethod;
@@ -283,6 +285,9 @@
case CHECK_CAST:
analyzeCheckCast(instruction.asCheckCast(), eligibleEnums);
break;
+ case INSTANCE_OF:
+ analyzeInstanceOf(instruction.asInstanceOf());
+ break;
case INIT_CLASS:
analyzeInitClass(instruction.asInitClass(), eligibleEnums);
break;
@@ -452,6 +457,14 @@
markEnumAsUnboxable(Reason.DOWN_CAST, enumClass);
}
+ private void analyzeInstanceOf(InstanceOf instanceOf) {
+ DexType baseType = instanceOf.type().toBaseType(factory);
+ DexProgramClass enumClass = getEnumUnboxingCandidateOrNull(baseType);
+ if (enumClass != null) {
+ markEnumAsUnboxable(Reason.INSTANCE_OF, enumClass);
+ }
+ }
+
private void analyzeInitClass(InitClass initClass, Set<DexType> eligibleEnums) {
DexProgramClass enumClass = getEnumUnboxingCandidateOrNull(initClass.getClassValue());
if (enumClass != null) {
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/enums/eligibility/Reason.java b/src/main/java/com/android/tools/r8/ir/optimize/enums/eligibility/Reason.java
index 3cf50f1..5199184 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/enums/eligibility/Reason.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/enums/eligibility/Reason.java
@@ -14,6 +14,7 @@
public static final Reason ANNOTATION = new StringReason("ANNOTATION");
public static final Reason PINNED = new StringReason("PINNED");
public static final Reason DOWN_CAST = new StringReason("DOWN_CAST");
+ public static final Reason INSTANCE_OF = new StringReason("INSTANCE_OF");
public static final Reason SUBENUM_SUBTYPES = new StringReason("SUBENUM_SUBTYPES");
public static final Reason SUBENUM_INVALID_HIERARCHY =
new StringReason("SUBENUM_INVALID_HIERARCHY");
diff --git a/src/test/java/com/android/tools/r8/enumunboxing/EnumUnboxingInstanceOfTest.java b/src/test/java/com/android/tools/r8/enumunboxing/EnumUnboxingInstanceOfTest.java
index 0e13ceb..45400ac 100644
--- a/src/test/java/com/android/tools/r8/enumunboxing/EnumUnboxingInstanceOfTest.java
+++ b/src/test/java/com/android/tools/r8/enumunboxing/EnumUnboxingInstanceOfTest.java
@@ -3,12 +3,12 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.enumunboxing;
-import static com.android.tools.r8.utils.codeinspector.AssertUtils.assertFailsCompilation;
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.codeinspector.EnumUnboxingInspector;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
@@ -28,14 +28,15 @@
@Test
public void test() throws Exception {
- assertFailsCompilation(
- () ->
- testForR8(parameters.getBackend())
- .addInnerClasses(getClass())
- .addKeepMainRule(Main.class)
- .enableInliningAnnotations()
- .setMinApi(parameters)
- .compile());
+ testForR8(parameters.getBackend())
+ .addInnerClasses(getClass())
+ .addKeepMainRule(Main.class)
+ .addEnumUnboxingInspector(EnumUnboxingInspector::assertNoEnumsUnboxed)
+ .enableInliningAnnotations()
+ .setMinApi(parameters)
+ .compile()
+ .run(parameters.getRuntime(), Main.class)
+ .assertSuccessWithOutputLines("false", "A");
}
static class Main {