Patch dynamic type using NullOrAbstractValue
Bug: 172528424
Change-Id: I8691c4cd2a1b17b254b24c081650e0fd7acbdf8b
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/fieldvalueanalysis/StaticFieldValueAnalysis.java b/src/main/java/com/android/tools/r8/ir/analysis/fieldvalueanalysis/StaticFieldValueAnalysis.java
index be89019..3ab1305 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/fieldvalueanalysis/StaticFieldValueAnalysis.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/fieldvalueanalysis/StaticFieldValueAnalysis.java
@@ -109,11 +109,19 @@
// Abstract value.
feedback.recordFieldHasAbstractValue(field, appView, getOrComputeAbstractValue(value, field));
+ setDynamicType(field, value, false);
+ }
+
+ private void setDynamicType(DexEncodedField field, Value value, boolean maybeNull) {
// Dynamic upper bound type.
TypeElement fieldType =
TypeElement.fromDexType(field.field.type, Nullability.maybeNull(), appView);
TypeElement dynamicUpperBoundType = value.getDynamicUpperBoundType(appView);
if (dynamicUpperBoundType.strictlyLessThan(fieldType, appView)) {
+ if (maybeNull && dynamicUpperBoundType.isDefinitelyNotNull()) {
+ assert dynamicUpperBoundType.isReferenceType();
+ dynamicUpperBoundType = dynamicUpperBoundType.asReferenceType().asMaybeNull();
+ }
feedback.markFieldHasDynamicUpperBoundType(field, dynamicUpperBoundType);
}
@@ -121,6 +129,9 @@
ClassTypeElement dynamicLowerBoundType = value.getDynamicLowerBoundType(appView);
if (dynamicLowerBoundType != null) {
assert dynamicLowerBoundType.lessThanOrEqual(dynamicUpperBoundType, appView);
+ if (maybeNull && dynamicLowerBoundType.isDefinitelyNotNull()) {
+ dynamicLowerBoundType = dynamicLowerBoundType.asMaybeNull().asClassType();
+ }
feedback.markFieldHasDynamicLowerBoundType(field, dynamicLowerBoundType);
}
}
@@ -134,7 +145,8 @@
}
feedback.recordFieldHasAbstractValue(
field, appView, NullOrAbstractValue.create(getOrComputeAbstractValue(valuePut, field)));
- // TODO(b/172528424): investigate if we can set the dynamic type if it's only null vs a value.
+
+ setDynamicType(field, valuePut, true);
}
private AbstractValue getOrComputeAbstractValue(Value value, DexEncodedField field) {
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/value/AbstractValue.java b/src/main/java/com/android/tools/r8/ir/analysis/value/AbstractValue.java
index 8bfecf4..e53f27b 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/value/AbstractValue.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/value/AbstractValue.java
@@ -106,6 +106,12 @@
if (equals(other)) {
return this;
}
+ if (isNull()) {
+ return NullOrAbstractValue.create(other);
+ }
+ if (other.isNull()) {
+ return NullOrAbstractValue.create(this);
+ }
return UnknownValue.getInstance();
}