Unbox enums through Objects#toString
Bug: b/185222995
Change-Id: Iaa308ded60fbd986dbeabce8e8fdd90a13a2a35c
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 7b8fd7a..bea580f 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
@@ -1556,6 +1556,10 @@
|| singleTargetReference == factory.objectsMethods.requireNonNullWithMessage) {
return Reason.ELIGIBLE;
}
+ if (singleTargetReference == factory.objectsMethods.toStringWithObject) {
+ addRequiredNameData(enumClass);
+ return Reason.ELIGIBLE;
+ }
return new UnsupportedLibraryInvokeReason(singleTargetReference);
}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/enums/EnumUnboxingRewriter.java b/src/main/java/com/android/tools/r8/ir/optimize/enums/EnumUnboxingRewriter.java
index 789c542..a1f987b 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/enums/EnumUnboxingRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/enums/EnumUnboxingRewriter.java
@@ -499,6 +499,8 @@
getSharedUtilityClass()
.ensureCheckNotZeroWithMessageMethod(appView, context, eventConsumer));
}
+ } else if (invokedMethod == factory.objectsMethods.toStringWithObject) {
+ rewriteStringValueOf(invoke, context, convertedEnums, instructionIterator, eventConsumer);
}
return;
}
@@ -506,17 +508,7 @@
// Calls to java.lang.String.
if (invokedMethod.getHolderType() == factory.stringType) {
if (invokedMethod == factory.stringMembers.valueOf) {
- assert invoke.arguments().size() == 1;
- Value argument = invoke.getFirstArgument();
- DexType enumType = getEnumClassTypeOrNull(argument, convertedEnums);
- if (enumType != null) {
- ProgramMethod stringValueOfMethod =
- getLocalUtilityClass(enumType)
- .ensureStringValueOfMethod(appView, context, eventConsumer);
- instructionIterator.replaceCurrentInstruction(
- new InvokeStatic(
- stringValueOfMethod.getReference(), invoke.outValue(), invoke.arguments()));
- }
+ rewriteStringValueOf(invoke, context, convertedEnums, instructionIterator, eventConsumer);
}
return;
}
@@ -574,6 +566,24 @@
}
}
+ private void rewriteStringValueOf(
+ InvokeStatic invoke,
+ ProgramMethod context,
+ Map<Instruction, DexType> convertedEnums,
+ InstructionListIterator instructionIterator,
+ EnumUnboxerMethodProcessorEventConsumer eventConsumer) {
+ assert invoke.arguments().size() == 1;
+ Value argument = invoke.getFirstArgument();
+ DexType enumType = getEnumClassTypeOrNull(argument, convertedEnums);
+ if (enumType != null) {
+ ProgramMethod stringValueOfMethod =
+ getLocalUtilityClass(enumType).ensureStringValueOfMethod(appView, context, eventConsumer);
+ instructionIterator.replaceCurrentInstruction(
+ new InvokeStatic(
+ stringValueOfMethod.getReference(), invoke.outValue(), invoke.arguments()));
+ }
+ }
+
public void rewriteNullCheck(
InstructionListIterator iterator,
InvokeMethod invoke,
diff --git a/src/test/java/com/android/tools/r8/enumunboxing/StringValueOfEnumUnboxingTest.java b/src/test/java/com/android/tools/r8/enumunboxing/StringValueOfEnumUnboxingTest.java
index d8c656d..a09183d 100644
--- a/src/test/java/com/android/tools/r8/enumunboxing/StringValueOfEnumUnboxingTest.java
+++ b/src/test/java/com/android/tools/r8/enumunboxing/StringValueOfEnumUnboxingTest.java
@@ -7,6 +7,7 @@
import com.android.tools.r8.NeverInline;
import com.android.tools.r8.TestParameters;
import java.util.List;
+import java.util.Objects;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
@@ -60,9 +61,17 @@
System.out.println(MyEnum.A.ordinal());
System.out.println(0);
stringValueOf();
+ objectsToString();
stringBuilder();
}
+ private static void objectsToString() {
+ System.out.println(getStringThroughObjects(MyEnum.A));
+ System.out.println("A");
+ System.out.println(getStringThroughObjects(null));
+ System.out.println("null");
+ }
+
private static void stringValueOf() {
System.out.println(getString(MyEnum.A));
System.out.println("A");
@@ -133,5 +142,10 @@
private static String getString(MyEnum e) {
return String.valueOf(e);
}
+
+ @NeverInline
+ private static String getStringThroughObjects(MyEnum e) {
+ return Objects.toString(e);
+ }
}
}