Update synthetic bridges after vertical class merging
This CL fixes an issue in the vertical class merger that has to do with synthetic bridge methods that get inserted during class merging.
The problem is that these bridge methods are created before vertical class merging is finished (meaning that the signatures of the bridges may change from the time they are created until vertical class merging finishes), and that the graph lense does not have any mappings for these intermediate method signatures". This CL therefore processes all the synthetic bridge methods when all classes have been merged.
Example: Consider that a virtual method "void A.foo(B)" is merged into the subtype of A. When that happens, a bridge method "void ASub.foo(B)" is created, which invokes the method "void ASub.foo$A(B)" via an invoke-direct instruction. After this bridge method has been created, the type B may be merged into its subtype, but the signature of the bridge method continues to be "void ASub.foo(B)". This is problematic, since the graph lense only provides capabilities for mapping back and forth from the end-signature "void ASub.foo(BSub)".
Change-Id: I6a65ecd103fe017d295a77c44f29cce4a17789a1
diff --git a/src/test/examples/classmerging/SyntheticBridgeSignaturesTest.java b/src/test/examples/classmerging/SyntheticBridgeSignaturesTest.java
new file mode 100644
index 0000000..a17d30a
--- /dev/null
+++ b/src/test/examples/classmerging/SyntheticBridgeSignaturesTest.java
@@ -0,0 +1,37 @@
+// Copyright (c) 2018, 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 classmerging;
+
+public class SyntheticBridgeSignaturesTest {
+
+ // If A is merged into ASub first, then the synthetic bridge for "void A.m(B)" will originally
+ // get the signature "void ASub.m(B)". Otherwise, if B is merged into BSub first, then the
+ // synthetic bridge will get the signature "void BSub.m(A)". In either case, it is important that
+ // the signatures of the bridge methods are updated after all classes have been merged vertically.
+ public static void main(String[] args) {
+ ASub a = new ASub();
+ BSub b = new BSub();
+ a.m(b);
+ b.m(a);
+ }
+
+ private static class A {
+
+ public void m(B object) {
+ System.out.println("In A.m()");
+ }
+ }
+
+ private static class ASub extends A {}
+
+ private static class B {
+
+ public void m(A object) {
+ System.out.println("In B.m()");
+ }
+ }
+
+ private static class BSub extends B {}
+}