Retain oneof fields with corresponding live oneof-case field
Change-Id: I00b0d343a2d146bbf4e45d9a50aba56fed6daa47
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/proto/schema/ProtoEnqueuerExtension.java b/src/main/java/com/android/tools/r8/ir/analysis/proto/schema/ProtoEnqueuerExtension.java
index 93add7b..ac6bcde 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/proto/schema/ProtoEnqueuerExtension.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/proto/schema/ProtoEnqueuerExtension.java
@@ -213,6 +213,76 @@
}
}
}
+
+ registerWriteToOneOfObjectsWithLiveOneOfCaseObject(protoMessageInfo, enqueuer, worklist);
+ }
+ }
+
+ /** Marks each oneof field whose corresponding oneof-case field is live as being written. */
+ private void registerWriteToOneOfObjectsWithLiveOneOfCaseObject(
+ ProtoMessageInfo protoMessageInfo, Enqueuer enqueuer, EnqueuerWorklist worklist) {
+ if (protoMessageInfo.numberOfOneOfObjects() == 0) {
+ return;
+ }
+
+ for (ProtoOneOfObjectPair oneOfObjectPair : protoMessageInfo.getOneOfObjects()) {
+ registerWriteToOneOfObjectIfOneOfCaseObjectIsLive(oneOfObjectPair, enqueuer, worklist);
+ }
+ }
+
+ /** Marks the given oneof field as being written if the corresponding oneof-case field is live. */
+ private void registerWriteToOneOfObjectIfOneOfCaseObjectIsLive(
+ ProtoOneOfObjectPair oneOfObjectPair, Enqueuer enqueuer, EnqueuerWorklist worklist) {
+ ProtoFieldObject oneOfCaseObject = oneOfObjectPair.getOneOfCaseObject();
+ if (!oneOfCaseObject.isLiveProtoFieldObject()) {
+ assert false;
+ return;
+ }
+
+ DexField oneOfCaseField = oneOfCaseObject.asLiveProtoFieldObject().getField();
+ DexEncodedField encodedOneOfCaseField = appView.appInfo().resolveField(oneOfCaseField);
+ if (encodedOneOfCaseField == null) {
+ assert false;
+ return;
+ }
+
+ DexClass clazz = appView.definitionFor(encodedOneOfCaseField.field.holder);
+ if (clazz == null || !clazz.isProgramClass()) {
+ assert false;
+ return;
+ }
+
+ DexEncodedMethod dynamicMethod = clazz.lookupVirtualMethod(references::isDynamicMethod);
+ if (dynamicMethod == null) {
+ assert false;
+ return;
+ }
+
+ if (!enqueuer.isFieldLive(encodedOneOfCaseField)) {
+ return;
+ }
+
+ ProtoFieldObject oneOfObject = oneOfObjectPair.getOneOfObject();
+ if (!oneOfObject.isLiveProtoFieldObject()) {
+ assert false;
+ return;
+ }
+
+ DexField oneOfField = oneOfObject.asLiveProtoFieldObject().getField();
+ DexEncodedField encodedOneOfField = appView.appInfo().resolveField(oneOfField);
+ if (encodedOneOfField == null) {
+ assert false;
+ return;
+ }
+
+ if (encodedOneOfField.field.holder != encodedOneOfCaseField.field.holder) {
+ assert false;
+ return;
+ }
+
+ if (enqueuer.registerFieldWrite(encodedOneOfField.field, dynamicMethod)) {
+ worklist.enqueueMarkReachableFieldAction(
+ clazz.asProgramClass(), encodedOneOfField, KeepReason.reflectiveUseIn(dynamicMethod));
}
}