Fix instanceGet on null
Change-Id: I67f64bb69af49c21f1b5f8c09a0acb081e339d58
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 fa88164..867c2dc 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
@@ -387,11 +387,15 @@
Value rewrittenOutValue =
code.createValue(
TypeElement.fromDexType(fieldMethod.getReturnType(), maybeNull(), appView));
+ Value in = instanceGet.object();
+ if (in.getType().isNullType()) {
+ iterator.previous();
+ in = iterator.insertConstIntInstruction(code, options, 0);
+ iterator.next();
+ }
InvokeStatic invoke =
new InvokeStatic(
- fieldMethod.getReference(),
- rewrittenOutValue,
- ImmutableList.of(instanceGet.object()));
+ fieldMethod.getReference(), rewrittenOutValue, ImmutableList.of(in));
iterator.replaceCurrentInstruction(invoke);
if (unboxedEnumsData.isUnboxedEnum(instanceGet.getField().type)) {
convertedEnums.put(invoke, instanceGet.getField().type);
@@ -529,6 +533,8 @@
if (invokedMethod == factory.javaLangSystemMembers.arraycopy) {
// Intentionally empty.
} else if (invokedMethod == factory.javaLangSystemMembers.identityHashCode) {
+ // Note that System.identityHashCode(null) == 0, so it works even if the input is null
+ // and not rewritten.
assert invoke.arguments().size() == 1;
Value argument = invoke.getFirstArgument();
DexType enumType = getEnumClassTypeOrNull(argument, convertedEnums);
diff --git a/src/test/java/com/android/tools/r8/enumunboxing/EnumUnboxNullArgumentTest.java b/src/test/java/com/android/tools/r8/enumunboxing/EnumUnboxNullArgumentTest.java
index c55ecf6..1f0492d 100644
--- a/src/test/java/com/android/tools/r8/enumunboxing/EnumUnboxNullArgumentTest.java
+++ b/src/test/java/com/android/tools/r8/enumunboxing/EnumUnboxNullArgumentTest.java
@@ -4,10 +4,6 @@
package com.android.tools.r8.enumunboxing;
-import static org.hamcrest.CoreMatchers.containsString;
-import static org.junit.Assert.assertThrows;
-
-import com.android.tools.r8.CompilationFailedException;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
@@ -29,24 +25,14 @@
}
@Test
- public void testR8() {
- // TODO(b/287193321): We should not fail compilation.
- assertThrows(
- CompilationFailedException.class,
- () ->
- testForR8(parameters.getBackend())
- .addInnerClasses(getClass())
- .setMinApi(parameters)
- .addKeepMainRule(Main.class)
- // TODO(b/287193321): Using LIR avoids the issue, is it fixed or just hidden?
- .addOptionsModification(options -> options.testing.disableLir())
- .compileWithExpectedDiagnostics(
- diagnostics -> {
- if (parameters.isDexRuntime()) {
- diagnostics.assertErrorMessageThatMatches(
- containsString("Cannot constrain type"));
- }
- }));
+ public void testR8() throws Exception {
+ testForR8(parameters.getBackend())
+ .addInnerClasses(getClass())
+ .setMinApi(parameters)
+ .addKeepMainRule(Main.class)
+ .addOptionsModification(options -> options.testing.disableLir())
+ .run(parameters.getRuntime(), Main.class)
+ .assertFailureWithErrorThatThrows(NullPointerException.class);
}
public enum MyEnum {