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 {