Add reproduction of issue 272346803

Bug: b/272346803
Change-Id: I33632768cf74d8b613ea3d6d0479d721555dd231
diff --git a/src/test/java/com/android/tools/r8/desugar/constantdynamic/ConstantDynamicMultipleConstantsWithDifferentSymbolicReferenceUsingSameBSMAndArgumentsTest.java b/src/test/java/com/android/tools/r8/desugar/constantdynamic/ConstantDynamicMultipleConstantsWithDifferentSymbolicReferenceUsingSameBSMAndArgumentsTest.java
new file mode 100644
index 0000000..9947216
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/desugar/constantdynamic/ConstantDynamicMultipleConstantsWithDifferentSymbolicReferenceUsingSameBSMAndArgumentsTest.java
@@ -0,0 +1,593 @@
+// Copyright (c) 2023, 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.desugar.constantdynamic;
+
+import static com.android.tools.r8.DiagnosticsMatcher.diagnosticMessage;
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.junit.Assert.assertThrows;
+import static org.junit.Assume.assumeTrue;
+
+import com.android.tools.r8.CompilationFailedException;
+import com.android.tools.r8.DesugarTestConfiguration;
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.TestParametersCollection;
+import com.android.tools.r8.TestRuntime.CfVm;
+import com.android.tools.r8.cf.CfVersion;
+import com.android.tools.r8.utils.AndroidApiLevel;
+import com.android.tools.r8.utils.StringUtils;
+import java.io.IOException;
+import java.lang.invoke.MethodHandles;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
+
+@RunWith(Parameterized.class)
+public class ConstantDynamicMultipleConstantsWithDifferentSymbolicReferenceUsingSameBSMAndArgumentsTest
+    extends TestBase {
+
+  @Parameter() public TestParameters parameters;
+
+  @Parameters(name = "{0}")
+  public static TestParametersCollection data() {
+    return getTestParameters().withAllRuntimes().withAllApiLevelsAlsoForCf().build();
+  }
+
+  private static final String MAIN_CLASS = "A";
+  private static final String EXPECTED_OUTPUT = StringUtils.lines("false");
+  private static final String UNEXPECTED_OUTPUT = StringUtils.lines("true");
+
+  @Test
+  public void testReference() throws Exception {
+    parameters.assumeJvmTestParameters();
+    assumeTrue(parameters.getRuntime().asCf().isNewerThanOrEqual(CfVm.JDK11));
+    testForJvm(parameters)
+        .addProgramClassFileData(classFileData)
+        .disassemble()
+        .run(parameters.getRuntime(), MAIN_CLASS)
+        .assertSuccessWithOutput(EXPECTED_OUTPUT);
+  }
+
+  @Test
+  public void testDesugaring() throws Exception {
+    testForDesugaring(parameters)
+        .addProgramClassFileData(classFileData)
+        .run(parameters.getRuntime(), MAIN_CLASS)
+        .applyIf(
+            // When not desugaring the CF code requires JDK 11.
+            DesugarTestConfiguration::isNotDesugared,
+            r -> {
+              if (parameters.isCfRuntime()
+                  && parameters.getRuntime().asCf().isNewerThanOrEqual(CfVm.JDK11)) {
+                r.assertSuccessWithOutput(EXPECTED_OUTPUT);
+              } else {
+                r.assertFailureWithErrorThatThrows(UnsupportedClassVersionError.class);
+              }
+            })
+        .applyIf(
+            DesugarTestConfiguration::isDesugared, r -> r.assertSuccessWithOutput(UNEXPECTED_OUTPUT));
+  }
+
+  @Test
+  public void testR8() throws Exception {
+    parameters.assumeR8TestParameters();
+    testForR8(parameters.getBackend())
+        .addProgramClassFileData(classFileData)
+        .setMinApi(parameters)
+        .addKeepMainRule(MAIN_CLASS)
+        // TODO(b/198142613): There should not be a warnings on class references which are
+        //  desugared away.
+        .applyIf(
+            parameters.getApiLevel().isLessThan(AndroidApiLevel.O),
+            b -> b.addDontWarn("java.lang.invoke.MethodHandles$Lookup"))
+        // TODO(b/198142625): Support CONSTANT_Dynamic output for class files.
+        .applyIf(
+            parameters.isCfRuntime(),
+            r -> {
+              assertThrows(
+                  CompilationFailedException.class,
+                  () ->
+                      r.compileWithExpectedDiagnostics(
+                          diagnostics -> {
+                            diagnostics.assertOnlyErrors();
+                            diagnostics.assertErrorsMatch(
+                                diagnosticMessage(
+                                    containsString(
+                                        "Unsupported dynamic constant (not desugaring)")));
+                          }));
+            },
+            r ->
+                r.run(parameters.getRuntime(), MAIN_CLASS)
+                    .assertSuccessWithOutput(UNEXPECTED_OUTPUT));
+  }
+
+  /*
+    This test was supposed to use the following test classes to have two dynamic constants
+    using exactly the same bootstrap method and arguments as set up in getTransformedClasses
+    below. However, ASM will canonicalize both dynamic constants and bootstrap methods, so instead
+    a class file directly from bytes is used.
+  */
+
+  private byte[] getTransformedClasses() throws IOException {
+      return transformer(A.class)
+          .setVersion(CfVersion.V11)
+          .transformConstStringToConstantDynamic(
+              "condy1", A.class, "myConstant", false, "constantName", Object.class)
+          .transformConstStringToConstantDynamic(
+              "condy2", A.class, "myConstant", false, "constantName", Object.class)
+          .transform();
+  }
+
+  public static class Main {
+
+    public static void main(String[] args) {
+      System.out.println(A.getConstant1() == A.getConstant2());
+    }
+  }
+
+  public static class A {
+
+    public static Object getConstant1() {
+      return "condy1"; // Will be transformed to Constant_DYNAMIC.
+    }
+
+    public static Object getConstant2() {
+      return "condy2"; // Will be transformed to Constant_DYNAMIC.
+    }
+
+    private static Object myConstant(MethodHandles.Lookup lookup, String name, Class<?> type) {
+      return new Object();
+    }
+  }
+
+/*
+
+Class file bytes for the following class file:
+
+Classfile A.class
+  Last modified Mar 17, 2023; size 1364 bytes
+  SHA-256 checksum 4379e359d727521479cee1aa5b6d711090b2777553454d9b667fe502a1b0daa9
+  Compiled from "A.java"
+public class A
+  minor version: 0
+  major version: 55
+  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+  this_class: #2                          // A
+  super_class: #4                         // java/lang/Object
+  interfaces: 0, fields: 0, methods: 5, attributes: 3
+Constant pool:
+   #1 = Utf8               A
+   #2 = Class              #1             // A
+   #3 = Utf8               java/lang/Object
+   #4 = Class              #3             // java/lang/Object
+   #5 = Utf8               A.java
+   #6 = Utf8               java/lang/invoke/MethodHandles$Lookup
+   #7 = Class              #6             // java/lang/invoke/MethodHandles$Lookup
+   #8 = Utf8               java/lang/invoke/MethodHandles
+   #9 = Class              #8             // java/lang/invoke/MethodHandles
+  #10 = Utf8               Lookup
+  #11 = Utf8               <init>
+  #12 = Utf8               ()V
+  #13 = NameAndType        #11:#12        // "<init>":()V
+  #14 = Methodref          #4.#13         // java/lang/Object."<init>":()V
+  #15 = Utf8               this
+  #16 = Utf8               LA;
+  #17 = Utf8               getConstant1
+  #18 = Utf8               ()Ljava/lang/Object;
+  #19 = Utf8               myConstant
+  #20 = Utf8               (Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Object;
+  #21 = NameAndType        #19:#20        // myConstant:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Object;
+  #22 = Methodref          #2.#21         // A.myConstant:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Object;
+  #23 = MethodHandle       6:#22          // REF_invokeStatic A.myConstant:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Object;
+  #24 = Utf8               constantName
+  #25 = Utf8               Ljava/lang/Object;
+  #26 = NameAndType        #24:#25        // constantName:Ljava/lang/Object;
+  #27 = Dynamic            #0:#26         // #0:constantName:Ljava/lang/Object;
+  #28 = Utf8               getConstant2
+  #29 = Dynamic            #1:#26         // #1:constantName:Ljava/lang/Object;
+  #30 = Utf8               (Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class<*>;)Ljava/lang/Object;
+  #31 = Utf8               lookup
+  #32 = Utf8               Ljava/lang/invoke/MethodHandles$Lookup;
+  #33 = Utf8               name
+  #34 = Utf8               Ljava/lang/String;
+  #35 = Utf8               type
+  #36 = Utf8               Ljava/lang/Class<*>;
+  #37 = Utf8               Ljava/lang/Class;
+  #38 = Utf8               main
+  #39 = Utf8               ([Ljava/lang/String;)V
+  #40 = Utf8               java/lang/System
+  #41 = Class              #40            // java/lang/System
+  #42 = Utf8               out
+  #43 = Utf8               Ljava/io/PrintStream;
+  #44 = NameAndType        #42:#43        // out:Ljava/io/PrintStream;
+  #45 = Fieldref           #41.#44        // java/lang/System.out:Ljava/io/PrintStream;
+  #46 = NameAndType        #17:#18        // getConstant1:()Ljava/lang/Object;
+  #47 = Methodref          #2.#46         // A.getConstant1:()Ljava/lang/Object;
+  #48 = NameAndType        #28:#18        // getConstant2:()Ljava/lang/Object;
+  #49 = Methodref          #2.#48         // A.getConstant2:()Ljava/lang/Object;
+  #50 = Utf8               java/io/PrintStream
+  #51 = Class              #50            // java/io/PrintStream
+  #52 = Utf8               [Ljava/lang/String;
+  #53 = Class              #52            // "[Ljava/lang/String;"
+  #54 = Utf8               println
+  #55 = Utf8               (Z)V
+  #56 = NameAndType        #54:#55        // println:(Z)V
+  #57 = Methodref          #51.#56        // java/io/PrintStream.println:(Z)V
+  #58 = Utf8               Code
+  #59 = Utf8               LineNumberTable
+  #60 = Utf8               LocalVariableTable
+  #61 = Utf8               LocalVariableTypeTable
+  #62 = Utf8               Signature
+  #63 = Utf8               StackMapTable
+  #64 = Utf8               InnerClasses
+  #65 = Utf8               SourceFile
+  #66 = Utf8               BootstrapMethods
+{
+  public A();
+    descriptor: ()V
+    flags: (0x0001) ACC_PUBLIC
+    Code:
+      stack=1, locals=1, args_size=1
+         0: aload_0
+         1: invokespecial #14                 // Method java/lang/Object."<init>":()V
+         4: return
+      LineNumberTable:
+        line 132: 0
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       5     0  this   LA;
+
+  public static java.lang.Object getConstant1();
+    descriptor: ()Ljava/lang/Object;
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    Code:
+      stack=1, locals=0, args_size=0
+         0: ldc           #27                 // Dynamic #0:constantName:Ljava/lang/Object;
+         2: areturn
+      LineNumberTable:
+        line 135: 0
+
+  public static java.lang.Object getConstant2();
+    descriptor: ()Ljava/lang/Object;
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    Code:
+      stack=1, locals=0, args_size=0
+         0: ldc           #29                 // Dynamic #1:constantName:Ljava/lang/Object;
+         2: areturn
+      LineNumberTable:
+        line 139: 0
+
+  private static java.lang.Object myConstant(java.lang.invoke.MethodHandles$Lookup, java.lang.String, java.lang.Class<?>);
+    descriptor: (Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Object;
+    flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+    Code:
+      stack=2, locals=3, args_size=3
+         0: new           #4                  // class java/lang/Object
+         3: dup
+         4: invokespecial #14                 // Method java/lang/Object."<init>":()V
+         7: areturn
+      LineNumberTable:
+        line 143: 0
+      LocalVariableTable:
+        Start  Length  Slot  Name   Signature
+            0       8     0 lookup   Ljava/lang/invoke/MethodHandles$Lookup;
+            0       8     1  name   Ljava/lang/String;
+            0       8     2  type   Ljava/lang/Class;
+      LocalVariableTypeTable:
+        Start  Length  Slot  Name   Signature
+            0       8     2  type   Ljava/lang/Class<*>;
+    Signature: #30                          // (Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class<*>;)Ljava/lang/Object;
+
+  public static void main(java.lang.String[]);
+    descriptor: ([Ljava/lang/String;)V
+    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+    Code:
+      stack=3, locals=1, args_size=1
+         0: getstatic     #45                 // Field java/lang/System.out:Ljava/io/PrintStream;
+         3: invokestatic  #47                 // Method getConstant1:()Ljava/lang/Object;
+         6: invokestatic  #49                 // Method getConstant2:()Ljava/lang/Object;
+         9: if_acmpne     16
+        12: iconst_1
+        13: goto          17
+        16: iconst_0
+        17: invokevirtual #57                 // Method java/io/PrintStream.println:(Z)V
+        20: return
+      StackMapTable: number_of_entries = 2
+        frame_type = 80 // same_locals_1_stack_item
+  stack = [ class java/io/PrintStream ]
+  frame_type = 255 // full_frame
+  offset_delta = 0
+  locals = [ class "[Ljava/lang/String;" ]
+  stack = [ class java/io/PrintStream, int ]
+  LineNumberTable:
+  line 12: 0
+  line 13: 20
+}
+InnerClasses:
+public static final #10= #7 of #9;      // Lookup=class java/lang/invoke/MethodHandles$Lookup of class java/lang/invoke/MethodHandles
+    SourceFile: "A.java"
+    BootstrapMethods:
+    0: #23 REF_invokeStatic A.myConstant:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Object;
+    Method arguments:
+    1: #23 REF_invokeStatic A.myConstant:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Object;
+    Method arguments:
+*/
+
+  private byte[] classFileData = {
+      -54, -2, -70, -66, 0, 0, 0, 55, 0, 67, 1, 0, 1, 65, 7, 0, 1,
+      1, 0, 16, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 79, 98, 106,
+      101, 99, 116, 7, 0, 3, 1, 0, 6, 65, 46, 106, 97, 118, 97, 1,
+      0, 37, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 105, 110, 118, 111,
+      107, 101, 47, 77, 101, 116, 104, 111, 100, 72, 97, 110, 100, 108, 101, 115,
+      36, 76, 111, 111, 107, 117, 112, 7, 0, 6, 1, 0, 30, 106, 97, 118,
+      97, 47, 108, 97, 110, 103, 47, 105, 110, 118, 111, 107, 101, 47, 77, 101,
+      116, 104, 111, 100, 72, 97, 110, 100, 108, 101, 115, 7, 0, 8, 1, 0,
+      6, 76, 111, 111, 107, 117, 112, 1, 0, 6, 60, 105, 110, 105, 116, 62,
+      1, 0, 3, 40, 41, 86, 12, 0, 11, 0, 12, 10, 0, 4, 0, 13,
+      1, 0, 4, 116, 104, 105, 115, 1, 0, 3, 76, 65, 59, 1, 0, 12,
+      103, 101, 116, 67, 111, 110, 115, 116, 97, 110, 116, 49, 1, 0, 20, 40,
+      41, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 79, 98, 106, 101,
+      99, 116, 59, 1, 0, 10, 109, 121, 67, 111, 110, 115, 116, 97, 110, 116,
+      1, 0, 94, 40, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 105,
+      110, 118, 111, 107, 101, 47, 77, 101, 116, 104, 111, 100, 72, 97, 110, 100,
+      108, 101, 115, 36, 76, 111, 111, 107, 117, 112, 59, 76, 106, 97, 118, 97,
+      47, 108, 97, 110, 103, 47, 83, 116, 114, 105, 110, 103, 59, 76, 106, 97,
+      118, 97, 47, 108, 97, 110, 103, 47, 67, 108, 97, 115, 115, 59, 41, 76,
+      106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 79, 98, 106, 101, 99, 116,
+      59, 12, 0, 19, 0, 20, 10, 0, 2, 0, 21, 15, 6, 0, 22, 1,
+      0, 12, 99, 111, 110, 115, 116, 97, 110, 116, 78, 97, 109, 101, 1, 0,
+      18, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 79, 98, 106, 101,
+      99, 116, 59, 12, 0, 24, 0, 25, 17, 0, 0, 0, 26, 1, 0, 12,
+      103, 101, 116, 67, 111, 110, 115, 116, 97, 110, 116, 50, 17, 0, 1, 0,
+      26, 1, 0, 97, 40, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47,
+      105, 110, 118, 111, 107, 101, 47, 77, 101, 116, 104, 111, 100, 72, 97, 110,
+      100, 108, 101, 115, 36, 76, 111, 111, 107, 117, 112, 59, 76, 106, 97, 118,
+      97, 47, 108, 97, 110, 103, 47, 83, 116, 114, 105, 110, 103, 59, 76, 106,
+      97, 118, 97, 47, 108, 97, 110, 103, 47, 67, 108, 97, 115, 115, 60, 42,
+      62, 59, 41, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 79, 98,
+      106, 101, 99, 116, 59, 1, 0, 6, 108, 111, 111, 107, 117, 112, 1, 0,
+      39, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 105, 110, 118, 111,
+      107, 101, 47, 77, 101, 116, 104, 111, 100, 72, 97, 110, 100, 108, 101, 115,
+      36, 76, 111, 111, 107, 117, 112, 59, 1, 0, 4, 110, 97, 109, 101, 1,
+      0, 18, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 83, 116, 114,
+      105, 110, 103, 59, 1, 0, 4, 116, 121, 112, 101, 1, 0, 20, 76, 106,
+      97, 118, 97, 47, 108, 97, 110, 103, 47, 67, 108, 97, 115, 115, 60, 42,
+      62, 59, 1, 0, 17, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47,
+      67, 108, 97, 115, 115, 59, 1, 0, 4, 109, 97, 105, 110, 1, 0, 22,
+      40, 91, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 83, 116, 114,
+      105, 110, 103, 59, 41, 86, 1, 0, 16, 106, 97, 118, 97, 47, 108, 97,
+      110, 103, 47, 83, 121, 115, 116, 101, 109, 7, 0, 40, 1, 0, 3, 111,
+      117, 116, 1, 0, 21, 76, 106, 97, 118, 97, 47, 105, 111, 47, 80, 114,
+      105, 110, 116, 83, 116, 114, 101, 97, 109, 59, 12, 0, 42, 0, 43, 9,
+      0, 41, 0, 44, 12, 0, 17, 0, 18, 10, 0, 2, 0, 46, 12, 0,
+      28, 0, 18, 10, 0, 2, 0, 48, 1, 0, 19, 106, 97, 118, 97, 47,
+      105, 111, 47, 80, 114, 105, 110, 116, 83, 116, 114, 101, 97, 109, 7, 0,
+      50, 1, 0, 19, 91, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47,
+      83, 116, 114, 105, 110, 103, 59, 7, 0, 52, 1, 0, 7, 112, 114, 105,
+      110, 116, 108, 110, 1, 0, 4, 40, 90, 41, 86, 12, 0, 54, 0, 55,
+      10, 0, 51, 0, 56, 1, 0, 4, 67, 111, 100, 101, 1, 0, 15, 76,
+      105, 110, 101, 78, 117, 109, 98, 101, 114, 84, 97, 98, 108, 101, 1, 0,
+      18, 76, 111, 99, 97, 108, 86, 97, 114, 105, 97, 98, 108, 101, 84, 97,
+      98, 108, 101, 1, 0, 22, 76, 111, 99, 97, 108, 86, 97, 114, 105, 97,
+      98, 108, 101, 84, 121, 112, 101, 84, 97, 98, 108, 101, 1, 0, 9, 83,
+      105, 103, 110, 97, 116, 117, 114, 101, 1, 0, 13, 83, 116, 97, 99, 107,
+      77, 97, 112, 84, 97, 98, 108, 101, 1, 0, 12, 73, 110, 110, 101, 114,
+      67, 108, 97, 115, 115, 101, 115, 1, 0, 10, 83, 111, 117, 114, 99, 101,
+      70, 105, 108, 101, 1, 0, 16, 66, 111, 111, 116, 115, 116, 114, 97, 112,
+      77, 101, 116, 104, 111, 100, 115, 0, 33, 0, 2, 0, 4, 0, 0, 0,
+      0, 0, 5, 0, 1, 0, 11, 0, 12, 0, 1, 0, 58, 0, 0, 0,
+      47, 0, 1, 0, 1, 0, 0, 0, 5, 42, -73, 0, 14, -79, 0, 0,
+      0, 2, 0, 59, 0, 0, 0, 6, 0, 1, 0, 0, 0, -124, 0, 60,
+      0, 0, 0, 12, 0, 1, 0, 0, 0, 5, 0, 15, 0, 16, 0, 0,
+      0, 9, 0, 17, 0, 18, 0, 1, 0, 58, 0, 0, 0, 27, 0, 1,
+      0, 0, 0, 0, 0, 3, 18, 27, -80, 0, 0, 0, 1, 0, 59, 0,
+      0, 0, 6, 0, 1, 0, 0, 0, -121, 0, 9, 0, 28, 0, 18, 0,
+      1, 0, 58, 0, 0, 0, 27, 0, 1, 0, 0, 0, 0, 0, 3, 18,
+      29, -80, 0, 0, 0, 1, 0, 59, 0, 0, 0, 6, 0, 1, 0, 0,
+      0, -117, 0, 10, 0, 19, 0, 20, 0, 2, 0, 58, 0, 0, 0, 88,
+      0, 2, 0, 3, 0, 0, 0, 8, -69, 0, 4, 89, -73, 0, 14, -80,
+      0, 0, 0, 3, 0, 59, 0, 0, 0, 6, 0, 1, 0, 0, 0, -113,
+      0, 60, 0, 0, 0, 32, 0, 3, 0, 0, 0, 8, 0, 31, 0, 32,
+      0, 0, 0, 0, 0, 8, 0, 33, 0, 34, 0, 1, 0, 0, 0, 8,
+      0, 35, 0, 37, 0, 2, 0, 61, 0, 0, 0, 12, 0, 1, 0, 0,
+      0, 8, 0, 35, 0, 36, 0, 2, 0, 62, 0, 0, 0, 2, 0, 30,
+      0, 9, 0, 38, 0, 39, 0, 1, 0, 58, 0, 0, 0, 75, 0, 3,
+      0, 1, 0, 0, 0, 21, -78, 0, 45, -72, 0, 47, -72, 0, 49, -90,
+      0, 7, 4, -89, 0, 4, 3, -74, 0, 57, -79, 0, 0, 0, 2, 0,
+      63, 0, 0, 0, 20, 0, 2, 80, 7, 0, 51, -1, 0, 0, 0, 1,
+      7, 0, 53, 0, 2, 7, 0, 51, 1, 0, 59, 0, 0, 0, 10, 0,
+      2, 0, 0, 0, 12, 0, 20, 0, 13, 0, 3, 0, 64, 0, 0, 0,
+      10, 0, 1, 0, 7, 0, 9, 0, 10, 0, 25, 0, 65, 0, 0, 0,
+      2, 0, 5, 0, 66, 0, 0, 0, 10, 0, 2, 0, 23, 0, 0, 0,
+      23, 0, 0
+  };
+
+  /*
+
+  The class file bytes above was generated from the following ASM visitor code using ASM with the
+  patch below applied (was applied on 443339a964352dcec4dd3915de8f13188920d3ac).
+
+  The thing to note is that the two calls
+
+    methodVisitor.visitLdcInsn(new ConstantDynamic(...));
+
+  have the exact same arguments, which ASM will canonicalize making it impossible to
+  write the test using standard ASM visitor.
+
+  import java.nio.file.Files;
+  import java.nio.file.Paths;
+
+  import org.objectweb.asm.AnnotationVisitor;
+  import org.objectweb.asm.Attribute;
+  import org.objectweb.asm.ClassReader;
+  import org.objectweb.asm.ClassWriter;
+  import org.objectweb.asm.ConstantDynamic;
+  import org.objectweb.asm.FieldVisitor;
+  import org.objectweb.asm.Handle;
+  import org.objectweb.asm.Label;
+  import org.objectweb.asm.MethodVisitor;
+  import org.objectweb.asm.Opcodes;
+  import org.objectweb.asm.RecordComponentVisitor;
+  import org.objectweb.asm.Type;
+  import org.objectweb.asm.TypePath;
+
+  public class DC implements Opcodes {
+
+    public static byte[] dump () throws Exception {
+
+      ClassWriter classWriter = new ClassWriter(0);
+      FieldVisitor fieldVisitor;
+      RecordComponentVisitor recordComponentVisitor;
+      MethodVisitor methodVisitor;
+      AnnotationVisitor annotationVisitor0;
+
+      classWriter.visit(V11, ACC_PUBLIC | ACC_SUPER, "A", null, "java/lang/Object", null);
+
+      classWriter.visitSource("A.java", null);
+
+      classWriter.visitInnerClass("java/lang/invoke/MethodHandles$Lookup", "java/lang/invoke/MethodHandles", "Lookup", ACC_PUBLIC | ACC_FINAL | ACC_STATIC);
+
+      {
+        methodVisitor = classWriter.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
+        methodVisitor.visitCode();
+        Label label0 = new Label();
+        methodVisitor.visitLabel(label0);
+        methodVisitor.visitLineNumber(132, label0);
+        methodVisitor.visitVarInsn(ALOAD, 0);
+        methodVisitor.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
+        methodVisitor.visitInsn(RETURN);
+        Label label1 = new Label();
+        methodVisitor.visitLabel(label1);
+        methodVisitor.visitLocalVariable("this", "LA;", null, label0, label1, 0);
+        methodVisitor.visitMaxs(1, 1);
+        methodVisitor.visitEnd();
+      }
+      {
+        methodVisitor = classWriter.visitMethod(ACC_PUBLIC | ACC_STATIC, "getConstant1", "()Ljava/lang/Object;", null, null);
+        methodVisitor.visitCode();
+        Label label0 = new Label();
+        methodVisitor.visitLabel(label0);
+        methodVisitor.visitLineNumber(135, label0);
+        methodVisitor.visitLdcInsn(new ConstantDynamic("constantName", "Ljava/lang/Object;", new Handle(Opcodes.H_INVOKESTATIC, "A", "myConstant", "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Object;", false), new Object[] {}));
+        methodVisitor.visitInsn(ARETURN);
+        methodVisitor.visitMaxs(1, 0);
+        methodVisitor.visitEnd();
+      }
+      {
+        methodVisitor = classWriter.visitMethod(ACC_PUBLIC | ACC_STATIC, "getConstant2", "()Ljava/lang/Object;", null, null);
+        methodVisitor.visitCode();
+        Label label0 = new Label();
+        methodVisitor.visitLabel(label0);
+        methodVisitor.visitLineNumber(139, label0);
+        methodVisitor.visitLdcInsn(new ConstantDynamic("constantName", "Ljava/lang/Object;", new Handle(Opcodes.H_INVOKESTATIC, "A", "myConstant", "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Object;", false), new Object[] {}));
+        methodVisitor.visitInsn(ARETURN);
+        methodVisitor.visitMaxs(1, 0);
+        methodVisitor.visitEnd();
+      }
+      {
+        methodVisitor = classWriter.visitMethod(ACC_PRIVATE | ACC_STATIC, "myConstant", "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Object;", "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class<*>;)Ljava/lang/Object;", null);
+        methodVisitor.visitCode();
+        Label label0 = new Label();
+        methodVisitor.visitLabel(label0);
+        methodVisitor.visitLineNumber(143, label0);
+        methodVisitor.visitTypeInsn(NEW, "java/lang/Object");
+        methodVisitor.visitInsn(DUP);
+        methodVisitor.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
+        methodVisitor.visitInsn(ARETURN);
+        Label label1 = new Label();
+        methodVisitor.visitLabel(label1);
+        methodVisitor.visitLocalVariable("lookup", "Ljava/lang/invoke/MethodHandles$Lookup;", null, label0, label1, 0);
+        methodVisitor.visitLocalVariable("name", "Ljava/lang/String;", null, label0, label1, 1);
+        methodVisitor.visitLocalVariable("type", "Ljava/lang/Class;", "Ljava/lang/Class<*>;", label0, label1, 2);
+        methodVisitor.visitMaxs(2, 3);
+        methodVisitor.visitEnd();
+      }
+      {
+        methodVisitor = classWriter.visitMethod(ACC_PUBLIC | ACC_STATIC, "main", "([Ljava/lang/String;)V", null, null);
+        methodVisitor.visitCode();
+        Label label0 = new Label();
+        methodVisitor.visitLabel(label0);
+        methodVisitor.visitLineNumber(12, label0);
+        methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+        methodVisitor.visitMethodInsn(INVOKESTATIC, "A", "getConstant1", "()Ljava/lang/Object;", false);
+        methodVisitor.visitMethodInsn(INVOKESTATIC, "A", "getConstant2", "()Ljava/lang/Object;", false);
+        Label label1 = new Label();
+        methodVisitor.visitJumpInsn(IF_ACMPNE, label1);
+        methodVisitor.visitInsn(ICONST_1);
+        Label label2 = new Label();
+        methodVisitor.visitJumpInsn(GOTO, label2);
+        methodVisitor.visitLabel(label1);
+        methodVisitor.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] {"java/io/PrintStream"});
+        methodVisitor.visitInsn(ICONST_0);
+        methodVisitor.visitLabel(label2);
+        methodVisitor.visitFrame(Opcodes.F_FULL, 1, new Object[] {"[Ljava/lang/String;"}, 2, new Object[] {"java/io/PrintStream", Opcodes.INTEGER});
+        methodVisitor.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Z)V", false);
+        Label label3 = new Label();
+        methodVisitor.visitLabel(label3);
+        methodVisitor.visitLineNumber(13, label3);
+        methodVisitor.visitInsn(RETURN);
+        methodVisitor.visitMaxs(3, 1);
+        methodVisitor.visitEnd();
+      }
+      classWriter.visitEnd();
+
+      return classWriter.toByteArray();
+    }
+
+    public static void main(String[] args) throws Exception {
+      Files.write(Paths.get("A.class"), DC.dump());
+    }
+  }
+
+  diff --git a/asm/src/main/java/org/objectweb/asm/SymbolTable.java b/asm/src/main/java/org/objectweb/asm/SymbolTable.java
+index a2f26f18..999620c5 100644
+--- a/asm/src/main/java/org/objectweb/asm/SymbolTable.java
++++ b/asm/src/main/java/org/objectweb/asm/SymbolTable.java
+@@ -922,17 +922,6 @@ final class SymbolTable {
+   private Symbol addConstantDynamicOrInvokeDynamicReference(
+       final int tag, final String name, final String descriptor, final int bootstrapMethodIndex) {
+     int hashCode = hash(tag, name, descriptor, bootstrapMethodIndex);
+-    Entry entry = get(hashCode);
+-    while (entry != null) {
+-      if (entry.tag == tag
+-          && entry.hashCode == hashCode
+-          && entry.data == bootstrapMethodIndex
+-          && entry.name.equals(name)
+-          && entry.value.equals(descriptor)) {
+-        return entry;
+-      }
+-      entry = entry.next;
+-    }
+     constantPool.put122(tag, bootstrapMethodIndex, addConstantNameAndType(name, descriptor));
+     return put(
+         new Entry(
+@@ -1094,24 +1083,6 @@ final class SymbolTable {
+  private Symbol addBootstrapMethod(final int offset, final int length, final int hashCode) {
+    final byte[] bootstrapMethodsData = bootstrapMethods.data;
+-    Entry entry = get(hashCode);
+-    while (entry != null) {
+-      if (entry.tag == Symbol.BOOTSTRAP_METHOD_TAG && entry.hashCode == hashCode) {
+-        int otherOffset = (int) entry.data;
+-        boolean isSameBootstrapMethod = true;
+-        for (int i = 0; i < length; ++i) {
+-          if (bootstrapMethodsData[offset + i] != bootstrapMethodsData[otherOffset + i]) {
+-            isSameBootstrapMethod = false;
+-            break;
+-          }
+-        }
+-        if (isSameBootstrapMethod) {
+-          bootstrapMethods.length = offset; // Revert to old position.
+-          return entry;
+-        }
+-      }
+-      entry = entry.next;
+-    }
+    return put(new Entry(bootstrapMethodCount++, Symbol.BOOTSTRAP_METHOD_TAG, offset, hashCode));
+  }
+
+*/
+
+}
diff --git a/src/test/java/com/android/tools/r8/desugar/constantdynamic/ConstantDynamicRegress272346803Test.java b/src/test/java/com/android/tools/r8/desugar/constantdynamic/ConstantDynamicRegress272346803Test.java
new file mode 100644
index 0000000..4d8d477
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/desugar/constantdynamic/ConstantDynamicRegress272346803Test.java
@@ -0,0 +1,160 @@
+// Copyright (c) 2023, 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.desugar.constantdynamic;
+
+import static com.android.tools.r8.DiagnosticsMatcher.diagnosticMessage;
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.junit.Assert.assertThrows;
+import static org.junit.Assume.assumeTrue;
+
+import com.android.tools.r8.CompilationFailedException;
+import com.android.tools.r8.DesugarTestConfiguration;
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.TestParametersCollection;
+import com.android.tools.r8.TestRuntime.CfVm;
+import com.android.tools.r8.cf.CfVersion;
+import com.android.tools.r8.utils.AndroidApiLevel;
+import com.android.tools.r8.utils.StringUtils;
+import java.io.IOException;
+import java.lang.invoke.MethodHandles;
+import java.util.Arrays;
+import java.util.List;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
+
+@RunWith(Parameterized.class)
+public class ConstantDynamicRegress272346803Test extends TestBase {
+
+  @Parameter() public TestParameters parameters;
+
+  @Parameters(name = "{0}")
+  public static TestParametersCollection data() {
+    return getTestParameters().withAllRuntimes().withAllApiLevelsAlsoForCf().build();
+  }
+
+  private static final Class<?> MAIN_CLASS = Main.class;
+  private static final String EXPECTED_OUTPUT = StringUtils.lines("A", "B");
+  private static final String UNEXPECTED_OUTPUT = StringUtils.lines("A", "A");
+
+  @Test
+  public void testReference() throws Exception {
+    parameters.assumeJvmTestParameters();
+    assumeTrue(parameters.getRuntime().asCf().isNewerThanOrEqual(CfVm.JDK11));
+    testForJvm(parameters)
+        .addProgramClasses(Main.class)
+        .addProgramClassFileData(getTransformedClasses())
+        .run(parameters.getRuntime(), MAIN_CLASS)
+        .assertSuccessWithOutput(EXPECTED_OUTPUT);
+  }
+
+  @Test
+  public void testDesugaring() throws Exception {
+    testForDesugaring(parameters)
+        .addProgramClasses(Main.class)
+        .addProgramClassFileData(getTransformedClasses())
+        .run(parameters.getRuntime(), MAIN_CLASS)
+        .applyIf(
+            // When not desugaring the CF code requires JDK 11.
+            DesugarTestConfiguration::isNotDesugared,
+            r -> {
+              if (parameters.isCfRuntime()
+                  && parameters.getRuntime().asCf().isNewerThanOrEqual(CfVm.JDK11)) {
+                r.assertSuccessWithOutput(EXPECTED_OUTPUT);
+              } else {
+                r.assertFailureWithErrorThatThrows(UnsupportedClassVersionError.class);
+              }
+            })
+        .applyIf(
+            DesugarTestConfiguration::isDesugared, r -> r.assertSuccessWithOutput(EXPECTED_OUTPUT));
+  }
+
+  @Test
+  public void testR8() throws Exception {
+    parameters.assumeR8TestParameters();
+    testForR8(parameters.getBackend())
+        .addProgramClasses(Main.class)
+        .addProgramClassFileData(getTransformedClasses())
+        .setMinApi(parameters)
+        .addKeepMainRule(MAIN_CLASS)
+        // Access modification is required for inlining the get method from the desugared constant
+        // dynamic class.
+        .allowAccessModification()
+        // TODO(b/198142613): There should not be a warnings on class references which are
+        //  desugared away.
+        .applyIf(
+            parameters.getApiLevel().isLessThan(AndroidApiLevel.O),
+            b -> b.addDontWarn("java.lang.invoke.MethodHandles$Lookup"))
+        // TODO(b/198142625): Support CONSTANT_Dynamic output for class files.
+        .applyIf(
+            parameters.isCfRuntime(),
+            r -> {
+              assertThrows(
+                  CompilationFailedException.class,
+                  () ->
+                      r.compileWithExpectedDiagnostics(
+                          diagnostics -> {
+                            diagnostics.assertOnlyErrors();
+                            diagnostics.assertErrorsMatch(
+                                diagnosticMessage(
+                                    containsString(
+                                        "Unsupported dynamic constant (not desugaring)")));
+                          }));
+            },
+            r ->
+                r.run(parameters.getRuntime(), MAIN_CLASS)
+                    .assertSuccessWithOutput(UNEXPECTED_OUTPUT));
+  }
+
+  private List<byte[]> getTransformedClasses() throws IOException {
+    return Arrays.asList(
+        transformer(A.class)
+            .setVersion(CfVersion.V11)
+            .transformConstStringToConstantDynamic(
+                "condy1", A.class, "myConstant", false, "constantName", String.class)
+            .transform(),
+        transformer(B.class)
+            .setVersion(CfVersion.V11)
+            .transformConstStringToConstantDynamic(
+                "condy1", B.class, "myConstant", false, "constantName", String.class)
+            .transform());
+  }
+
+  // When R8 optimize this code the getter for the two constant dynamics will be inlined into
+  // Main.main. This leaves the synthetic constant dynamic classes with just two static fields.
+  // The synthetic sharing then share these two synthetics leaving only one constant.
+  // See b/272346803 for details.
+  public static class Main {
+
+    public static void main(String[] args) {
+      System.out.println(A.getConstant());
+      System.out.println(B.getConstant());
+    }
+  }
+
+  public static class A {
+
+    public static String getConstant() {
+      return "condy1"; // Will be transformed to Constant_DYNAMIC.
+    }
+
+    private static Object myConstant(MethodHandles.Lookup lookup, String name, Class<?> type) {
+      return "A";
+    }
+  }
+
+  public static class B {
+
+    public static String getConstant() {
+      return "condy1"; // Will be transformed to Constant_DYNAMIC.
+    }
+
+    private static Object myConstant(MethodHandles.Lookup lookup, String name, Class<?> type) {
+      return "B";
+    }
+  }
+}