Fix enum unboxing bug in presence of subclasses
Bug: b/500074331
Change-Id: Ibf9343de9e98c44d7cc5f8f57559f4a07759538d
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/enums/EnumUnboxingLens.java b/src/main/java/com/android/tools/r8/ir/optimize/enums/EnumUnboxingLens.java
index 33e9763..7a01842 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/enums/EnumUnboxingLens.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/enums/EnumUnboxingLens.java
@@ -108,7 +108,10 @@
AbstractValue unboxedEnumValue,
DexType enumType) {
DexMethod enumMethod = method.withHolder(enumType, dexItemFactory());
- DexMethod rewrittenEnumMethod = newMethodSignatures.getRepresentativeValue(enumMethod);
+ DexMethod rewrittenEnumMethod = methodMap.apply(enumMethod);
+ if (rewrittenEnumMethod == null) {
+ rewrittenEnumMethod = newMethodSignatures.getRepresentativeValue(enumMethod);
+ }
if (!unboxedEnumValue.isSingleNumberValue()) {
return rewrittenEnumMethod;
}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/info/MutableMethodOptimizationInfo.java b/src/main/java/com/android/tools/r8/ir/optimize/info/MutableMethodOptimizationInfo.java
index 791093e..666b867 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/info/MutableMethodOptimizationInfo.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/info/MutableMethodOptimizationInfo.java
@@ -784,8 +784,15 @@
dynamicType.getDynamicUpperBoundType(staticReturnType);
TypeElement newDynamicUpperBoundType =
newDynamicType.getDynamicUpperBoundType(staticReturnType);
+ // Check that the new dynamic return type is compatible with the old dynamic return type.
+ // It should generally always be stronger, but there are a few cases where this is not
+ // guaranteed, for example, due to the fact that we can reason precisely about virtual
+ // dispatch when we have a specific receiver type, but not about the behavior of _dispatch_
+ // methods inserted by enum unboxing, even when the dispatch argument is constant.
assert newDynamicUpperBoundType.lessThanOrEqualUpToNullability(
- previousDynamicUpperBoundType, appView)
+ previousDynamicUpperBoundType, appView)
+ || previousDynamicUpperBoundType.lessThanOrEqualUpToNullability(
+ newDynamicUpperBoundType, appView)
: "upper bound type changed from "
+ previousDynamicUpperBoundType
+ " to "
diff --git a/src/test/java/com/android/tools/r8/enumunboxing/EnumWithSubclassOverrideTest.java b/src/test/java/com/android/tools/r8/enumunboxing/EnumWithSubclassOverrideTest.java
index 4dcb4b3..9127324 100644
--- a/src/test/java/com/android/tools/r8/enumunboxing/EnumWithSubclassOverrideTest.java
+++ b/src/test/java/com/android/tools/r8/enumunboxing/EnumWithSubclassOverrideTest.java
@@ -49,8 +49,7 @@
.addEnumUnboxingInspector(inspector -> inspector.assertUnboxed(MyEnum.class))
.compile()
.run(parameters.getRuntime(), Main.class)
- // TODO(b/500074331): Should print "Sub B side effect".
- .assertSuccessWithOutputLines("Base copy A", "Base copy B");
+ .assertSuccessWithOutputLines("Sub B side effect", "Base copy A", "Base copy B");
}
static class Main {