Disallow class merging in presence of pinned signatures in full mode

Bug: b/344363457
Change-Id: I0af954a6ca2d4eeb8b9326e9e7673813e2de1e75
diff --git a/src/main/java/com/android/tools/r8/graph/DexEncodedField.java b/src/main/java/com/android/tools/r8/graph/DexEncodedField.java
index 5f72db6..bdea90a 100644
--- a/src/main/java/com/android/tools/r8/graph/DexEncodedField.java
+++ b/src/main/java/com/android/tools/r8/graph/DexEncodedField.java
@@ -302,6 +302,7 @@
     return true;
   }
 
+  @Override
   public FieldTypeSignature getGenericSignature() {
     return genericSignature;
   }
diff --git a/src/main/java/com/android/tools/r8/graph/DexEncodedMember.java b/src/main/java/com/android/tools/r8/graph/DexEncodedMember.java
index f7cc258..0365247 100644
--- a/src/main/java/com/android/tools/r8/graph/DexEncodedMember.java
+++ b/src/main/java/com/android/tools/r8/graph/DexEncodedMember.java
@@ -4,6 +4,7 @@
 package com.android.tools.r8.graph;
 
 import com.android.tools.r8.androidapi.ComputedApiLevel;
+import com.android.tools.r8.graph.GenericSignature.DexDefinitionSignature;
 import com.android.tools.r8.ir.optimize.info.MemberOptimizationInfo;
 import com.android.tools.r8.kotlin.KotlinMemberLevelInfo;
 import java.util.function.Consumer;
@@ -40,6 +41,8 @@
 
   public abstract void clearKotlinInfo();
 
+  public abstract DexDefinitionSignature<?> getGenericSignature();
+
   public abstract void clearGenericSignature();
 
   public DexType getHolderType() {
diff --git a/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java b/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java
index 6c86c27..bd27dfc 100644
--- a/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java
+++ b/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java
@@ -1372,6 +1372,7 @@
     }
   }
 
+  @Override
   public MethodTypeSignature getGenericSignature() {
     return genericSignature;
   }
diff --git a/src/main/java/com/android/tools/r8/graph/GenericSignature.java b/src/main/java/com/android/tools/r8/graph/GenericSignature.java
index a339bde..29fc029 100644
--- a/src/main/java/com/android/tools/r8/graph/GenericSignature.java
+++ b/src/main/java/com/android/tools/r8/graph/GenericSignature.java
@@ -122,7 +122,7 @@
     return EMPTY_TYPE_SIGNATURES;
   }
 
-  interface DexDefinitionSignature<T extends DexDefinition> {
+  public interface DexDefinitionSignature<T extends DexDefinition> {
 
     default boolean isClassSignature() {
       return false;
diff --git a/src/main/java/com/android/tools/r8/horizontalclassmerging/policies/NoKeepRules.java b/src/main/java/com/android/tools/r8/horizontalclassmerging/policies/NoKeepRules.java
index 63461b5..fe5ea8b 100644
--- a/src/main/java/com/android/tools/r8/horizontalclassmerging/policies/NoKeepRules.java
+++ b/src/main/java/com/android/tools/r8/horizontalclassmerging/policies/NoKeepRules.java
@@ -9,7 +9,9 @@
 import com.android.tools.r8.graph.DexEncodedMember;
 import com.android.tools.r8.graph.DexProgramClass;
 import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.GenericSignature.DexDefinitionSignature;
 import com.android.tools.r8.horizontalclassmerging.SingleClassPolicy;
+import com.android.tools.r8.shaking.KeepInfo;
 import com.android.tools.r8.shaking.KeepInfoCollection;
 import com.android.tools.r8.utils.InternalOptions;
 import com.google.common.collect.Iterables;
@@ -33,9 +35,9 @@
 
   private void processClass(DexProgramClass clazz) {
     DexType type = clazz.getType();
-    boolean pinHolder = keepInfo.getClassInfo(clazz).isPinned(options);
+    boolean pinHolder = isPinned(keepInfo.getClassInfo(clazz), clazz.getClassSignature());
     for (DexEncodedMember<?, ?> member : clazz.members()) {
-      if (keepInfo.getMemberInfo(member, clazz).isPinned(options)) {
+      if (isPinned(keepInfo.getMemberInfo(member, clazz), member.getGenericSignature())) {
         pinHolder = true;
         Iterables.addAll(
             dontMergeTypes,
@@ -49,6 +51,13 @@
     }
   }
 
+  private boolean isPinned(KeepInfo<?, ?> keepInfo, DexDefinitionSignature<?> genericSignature) {
+    return keepInfo.isPinned(options)
+        || (genericSignature.hasSignature()
+            && !options.isForceProguardCompatibilityEnabled()
+            && !keepInfo.isSignatureRemovalAllowed(options));
+  }
+
   @Override
   public boolean canMerge(DexProgramClass program) {
     return !dontMergeTypes.contains(program.getType());