Disable merging in presence of shadowed fields
Bug: b/348202700
Change-Id: Ib36655cb4c590fb75afa4f3aa54ff98f75632ef4
diff --git a/src/main/java/com/android/tools/r8/verticalclassmerging/VerticalClassMergerPolicyScheduler.java b/src/main/java/com/android/tools/r8/verticalclassmerging/VerticalClassMergerPolicyScheduler.java
index e50986a..4882a7d 100644
--- a/src/main/java/com/android/tools/r8/verticalclassmerging/VerticalClassMergerPolicyScheduler.java
+++ b/src/main/java/com/android/tools/r8/verticalclassmerging/VerticalClassMergerPolicyScheduler.java
@@ -23,6 +23,7 @@
import com.android.tools.r8.verticalclassmerging.policies.NoNestedMergingPolicy;
import com.android.tools.r8.verticalclassmerging.policies.NoNonSerializableClassIntoSerializableClassPolicy;
import com.android.tools.r8.verticalclassmerging.policies.NoServiceInterfacesPolicy;
+import com.android.tools.r8.verticalclassmerging.policies.NoShadowedFieldsPolicy;
import com.android.tools.r8.verticalclassmerging.policies.SameApiReferenceLevelPolicy;
import com.android.tools.r8.verticalclassmerging.policies.SameFeatureSplitPolicy;
import com.android.tools.r8.verticalclassmerging.policies.SameMainDexGroupPolicy;
@@ -57,6 +58,7 @@
new NoInvokeSuperNoSuchMethodErrorsPolicy(appView),
new SuccessfulVirtualMethodResolutionInTargetPolicy(appView),
new NoAbstractMethodsOnAbstractClassesPolicy(appView),
+ new NoShadowedFieldsPolicy(appView),
new NoNestedMergingPolicy());
}
}
diff --git a/src/main/java/com/android/tools/r8/verticalclassmerging/policies/NoShadowedFieldsPolicy.java b/src/main/java/com/android/tools/r8/verticalclassmerging/policies/NoShadowedFieldsPolicy.java
new file mode 100644
index 0000000..31c6cb2
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/verticalclassmerging/policies/NoShadowedFieldsPolicy.java
@@ -0,0 +1,38 @@
+// Copyright (c) 2024, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+package com.android.tools.r8.verticalclassmerging.policies;
+
+import com.android.tools.r8.graph.AppView;
+import com.android.tools.r8.shaking.AppInfoWithLiveness;
+import com.android.tools.r8.utils.TraversalContinuation;
+import com.android.tools.r8.verticalclassmerging.VerticalMergeGroup;
+
+public class NoShadowedFieldsPolicy extends VerticalClassMergerPolicy {
+
+ private final AppView<AppInfoWithLiveness> appView;
+
+ public NoShadowedFieldsPolicy(AppView<AppInfoWithLiveness> appView) {
+ this.appView = appView;
+ }
+
+ @Override
+ public boolean canMerge(VerticalMergeGroup group) {
+ TraversalContinuation<?, ?> traversalContinuation =
+ group
+ .getTarget()
+ .traverseProgramFields(
+ field ->
+ TraversalContinuation.breakIf(
+ appView
+ .appInfo()
+ .resolveFieldOn(group.getSource(), field.getReference())
+ .isSingleFieldResolutionResult()));
+ return traversalContinuation.isContinue();
+ }
+
+ @Override
+ public String getName() {
+ return "NoShadowedFieldsPolicy";
+ }
+}
diff --git a/src/test/java/com/android/tools/r8/classmerging/vertical/ShadowedNonReboundFieldVerticalClassMergingTest.java b/src/test/java/com/android/tools/r8/classmerging/vertical/ShadowedNonReboundFieldVerticalClassMergingTest.java
index e5b4562..c2abe25 100644
--- a/src/test/java/com/android/tools/r8/classmerging/vertical/ShadowedNonReboundFieldVerticalClassMergingTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/vertical/ShadowedNonReboundFieldVerticalClassMergingTest.java
@@ -7,6 +7,7 @@
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
+import com.android.tools.r8.utils.codeinspector.VerticallyMergedClassesInspector;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
@@ -39,13 +40,12 @@
.addInnerClasses(getClass())
.addKeepMainRule(Main.class)
.addVerticallyMergedClassesInspector(
- inspector -> inspector.assertMergedIntoSubtype(B.class).assertNoOtherClassesMerged())
+ VerticallyMergedClassesInspector::assertNoClassesMerged)
.enableNoVerticalClassMergingAnnotations()
.setMinApi(parameters)
.compile()
.run(parameters.getRuntime(), Main.class)
- // TODO(b/348202700): Should succeed with "1", "2", "2".
- .assertSuccessWithOutputLines("1", "2", "1");
+ .assertSuccessWithOutputLines("1", "2", "2");
}
static class Main {