changeset 2011:ae6493366e11

Add annotation-based framework for testing bridge generation
author mcimadamore
date Thu, 18 Apr 2013 10:33:07 +0100
parents b0716aee0da8
children 3daa696a6f88
files test/tools/javac/defaultMethods/TestInterfaceBridges.java test/tools/javac/generics/bridges/Bridge.java test/tools/javac/generics/bridges/BridgeHarness.java test/tools/javac/generics/bridges/Bridges.java test/tools/javac/generics/bridges/tests/TestBridgeWithDefault.java test/tools/javac/generics/bridges/tests/TestClassAndInterfaceBridgeIdentical01.java test/tools/javac/generics/bridges/tests/TestClassAndInterfaceBridgeIdentical02.java test/tools/javac/generics/bridges/tests/TestNoBridgeInSiblingsSuper.java test/tools/javac/generics/bridges/tests/TestNoDuplicateBridges01.java test/tools/javac/generics/bridges/tests/TestNoDuplicateBridges02.java
diffstat 10 files changed, 492 insertions(+), 86 deletions(-) [+]
line wrap: on
line diff
--- a/test/tools/javac/defaultMethods/TestInterfaceBridges.java	Wed Apr 17 19:54:16 2013 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,86 +0,0 @@
-/*
- * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
- * @summary Add experimental support for interface bridging
- * @compile -XDallowInterfaceBridges TestInterfaceBridges.java
- * @run main TestInterfaceBridges
- */
-
-import com.sun.tools.classfile.ClassFile;
-import com.sun.tools.classfile.ConstantPool.*;
-import com.sun.tools.classfile.Method;
-
-import java.io.*;
-
-public class TestInterfaceBridges {
-
-    interface A1 { Object m(); }
-    interface A2 { Object m(); }
-    interface B extends A1, A2 { B m(); }
-
-    static final String TEST_NAME = B.class.getName() + ".class" ;
-    static final String TEST_METHOD_NAME = "m";
-    static final String[] SIGS = new String[] { "()LTestInterfaceBridges$B;", "()Ljava/lang/Object;" };
-
-    public static void main(String... args) throws Exception {
-        new TestInterfaceBridges().run();
-    }
-
-    public void run() throws Exception {
-        String workDir = System.getProperty("test.classes");
-        checkInterfaceBridges(new File(workDir, TEST_NAME));
-    }
-
-    void checkInterfaceBridges(File f) {
-        System.err.println("check: " + f);
-        try {
-            ClassFile cf = ClassFile.read(f);
-            boolean[] sigFound = new boolean[] { false, false };
-            for (Method m : cf.methods) {
-                String mname = m.getName(cf.constant_pool);
-                if (mname.equals(TEST_METHOD_NAME)) {
-                    System.err.println(m.descriptor.getValue(cf.constant_pool));
-                    for (int i = 0 ; i < SIGS.length ; i++) {
-                        if (SIGS[i].equals(m.descriptor.getValue(cf.constant_pool))) {
-                            if (sigFound[i]) {
-                                throw new AssertionError("Duplicate method found: " + SIGS[i]);
-                            } else {
-                                sigFound[i] = true;
-                            }
-                        }
-                    }
-                }
-            }
-            for (int i = 0 ; i < sigFound.length ; i++) {
-                if (!sigFound[i]) {
-                    throw new AssertionError("Method not found: " + SIGS[i]);
-                }
-            }
-        } catch (Exception e) {
-            e.printStackTrace();
-            throw new Error("error reading " + f +": " + e);
-        }
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/generics/bridges/Bridge.java	Thu Apr 18 10:33:07 2013 +0100
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+import java.lang.annotation.Repeatable;
+
+@Repeatable(Bridges.class)
+@interface Bridge {
+    String value();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/generics/bridges/BridgeHarness.java	Thu Apr 18 10:33:07 2013 +0100
@@ -0,0 +1,218 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @library /tools/javac/lib
+ * @build JavacTestingAbstractProcessor BridgeHarness
+ * @run main BridgeHarness
+ */
+
+import com.sun.source.util.JavacTask;
+import com.sun.tools.classfile.AccessFlags;
+import com.sun.tools.classfile.ClassFile;
+import com.sun.tools.classfile.ConstantPool;
+import com.sun.tools.classfile.ConstantPoolException;
+import com.sun.tools.classfile.Method;
+import com.sun.tools.javac.code.Symbol.ClassSymbol;
+import com.sun.tools.javac.util.List;
+
+import java.io.File;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+import javax.annotation.processing.RoundEnvironment;
+import javax.annotation.processing.SupportedAnnotationTypes;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.TypeElement;
+import javax.tools.JavaCompiler;
+import javax.tools.JavaFileObject;
+import javax.tools.StandardJavaFileManager;
+import javax.tools.ToolProvider;
+
+import static javax.tools.StandardLocation.*;
+
+public class BridgeHarness {
+
+    /** number of errors found (must be zero for the test to pass) */
+    static int nerrors = 0;
+
+    /** the (shared) Java compiler used for compiling the tests */
+    static final JavaCompiler comp = ToolProvider.getSystemJavaCompiler();
+    
+    /** the (shared) file manager used by the compiler */
+    static final StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null);
+
+    public static void main(String[] args) throws Exception {
+        //set sourcepath
+        fm.setLocation(SOURCE_PATH,
+                Arrays.asList(new File(System.getProperty("test.src"), "tests")));
+        //set output (-d)
+        fm.setLocation(javax.tools.StandardLocation.CLASS_OUTPUT,
+                Arrays.asList(new File(System.getProperty("user.dir"))));
+        for (JavaFileObject jfo : fm.list(SOURCE_PATH, "", Collections.singleton(JavaFileObject.Kind.SOURCE), true)) {
+            //for each source, compile and check against annotations
+            new BridgeHarness(jfo).compileAndCheck();
+        }
+        //if there were errors, fail
+        if (nerrors > 0) {
+            throw new AssertionError("Errors were found");
+        }
+    }
+    
+    /* utility methods */
+    
+    /**
+     * Remove an element from a list
+     */
+    static <Z> List<Z> drop(List<Z> lz, Z z) {
+        if (lz.head == z) {
+            return drop(lz.tail, z);
+        } else if (lz.isEmpty()) {
+            return lz;
+        } else {
+            return drop(lz.tail, z).prepend(lz.head);
+        }
+    }
+    
+    /**
+     * return a string representation of a bytecode method
+     */
+    static String descriptor(Method m, ConstantPool cp) throws ConstantPoolException {
+        return m.getName(cp) + m.descriptor.getValue(cp);
+    }
+    
+    /* test harness */
+
+    /** Test file to be compiled */
+    JavaFileObject jfo;
+    
+    /** Mapping between class name and list of bridges in class with that name */
+    Map<String, List<Bridge>> bridgesMap = new HashMap<String, List<Bridge>>();
+
+    protected BridgeHarness(JavaFileObject jfo) {
+        this.jfo = jfo;
+    }
+
+    /**
+     * Compile a test using a custom annotation processor and check the generated
+     * bytecode against discovered annotations.
+     */
+    protected void compileAndCheck() throws Exception {
+        JavacTask ct = (JavacTask)comp.getTask(null, fm, null,
+                Arrays.asList("-XDallowInterfaceBridges"),
+                null, Arrays.asList(jfo));
+        ct.setProcessors(Collections.singleton(new BridgeFinder()));
+        
+        for (JavaFileObject jfo : ct.generate()) {
+            checkBridges(jfo);
+        }
+    }
+    
+    /**
+     * Check that every bridge in the generated classfile has a matching bridge
+     * annotation in the bridge map
+     */
+    protected void checkBridges(JavaFileObject jfo) {
+        try {            
+            ClassFile cf = ClassFile.read(jfo.openInputStream());
+            System.err.println("checking: " + cf.getName());
+            
+            List<Bridge> bridgeList = bridgesMap.get(cf.getName());            
+            if (bridgeList == null) {
+                //no bridges - nothing to check;
+                bridgeList = List.nil();
+            }
+
+            for (Method m : cf.methods) {
+                if (m.access_flags.is(AccessFlags.ACC_SYNTHETIC | AccessFlags.ACC_BRIDGE)) {
+                    //this is a bridge - see if there's a match in the bridge list
+                    Bridge match = null;
+                    for (Bridge b : bridgeList) {
+                        if (b.value().equals(descriptor(m, cf.constant_pool))) {
+                            match = b;
+                            break;
+                        }
+                    }
+                    if (match == null) {
+                        error("No annotation for bridge method: " + descriptor(m, cf.constant_pool));
+                    } else {
+                        bridgeList = drop(bridgeList, match);
+                    }
+                }
+            }
+            if (bridgeList.nonEmpty()) {
+                error("Redundant bridge annotation found: " + bridgeList.head.value());
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw new Error("error reading " + jfo.toUri() +": " + e);
+        }
+    }
+
+    /**
+     * Log an error
+     */
+    protected void error(String msg) {
+        nerrors++;
+        System.err.printf("Error occurred while checking file: %s\nreason: %s\n", jfo.getName(), msg);
+    }
+
+    /**
+     * This annotation processor is used to populate the bridge map with the
+     * contents of the annotations that are found on the tests being compiled
+     */
+    @SupportedAnnotationTypes({"Bridges","Bridge"})
+    class BridgeFinder extends JavacTestingAbstractProcessor {
+        @Override
+        public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
+            if (roundEnv.processingOver())
+                return true;
+            
+            TypeElement bridgeAnno = elements.getTypeElement("Bridge");
+            TypeElement bridgesAnno = elements.getTypeElement("Bridges");
+
+            //see if there are repeated annos
+            for (Element elem: roundEnv.getElementsAnnotatedWith(bridgesAnno)) {
+                List<Bridge> bridgeList = List.nil();
+                Bridges bridges = elem.getAnnotation(Bridges.class);
+                for (Bridge bridge : bridges.value()) {
+                    bridgeList = bridgeList.prepend(bridge);
+                }
+                bridgesMap.put(((ClassSymbol)elem).flatname.toString(), bridgeList);
+            }
+            
+            //see if there are non-repeated annos
+            for (Element elem: roundEnv.getElementsAnnotatedWith(bridgeAnno)) {
+                Bridge bridge = elem.getAnnotation(Bridge.class);
+                bridgesMap.put(((ClassSymbol)elem).flatname.toString(),
+                        List.of(bridge));
+            }
+            
+            return true;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/generics/bridges/Bridges.java	Thu Apr 18 10:33:07 2013 +0100
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+@interface Bridges {
+    Bridge[] value();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/generics/bridges/tests/TestBridgeWithDefault.java	Thu Apr 18 10:33:07 2013 +0100
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+class TestBridgeWithDefault {
+    interface A { Object m(int x); }
+
+    @Bridge("m(I)Ljava/lang/Object;")
+    interface B extends A {
+        String m(int x);
+        default Integer m(long x) { return null; }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/generics/bridges/tests/TestClassAndInterfaceBridgeIdentical01.java	Thu Apr 18 10:33:07 2013 +0100
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+class TestClassAndInterfaceBridgeIdentical01 {
+
+    interface A { Object m(); }
+    interface B { Number m(); }
+
+    @Bridge("m()Ljava/lang/Object;")
+    @Bridge("m()Ljava/lang/Number;")
+    interface C extends A, B {
+        Integer m();
+    }
+
+    @Bridge("m()Ljava/lang/Object;")
+    @Bridge("m()Ljava/lang/Number;")
+    static abstract class D implements A, B {
+        public abstract Integer m();
+    }
+
+    @Bridge("m()Ljava/lang/Object;")
+    @Bridge("m()Ljava/lang/Number;")
+    static class E implements A, B {
+        public Integer m() { return 1; }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/generics/bridges/tests/TestClassAndInterfaceBridgeIdentical02.java	Thu Apr 18 10:33:07 2013 +0100
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+class TestClassAndInterfaceBridgeIdentical02 {
+
+    interface A<X extends Object> { void m(X x); }
+    interface B<X extends Number> { void m(X x); }
+
+    @Bridge("m(Ljava/lang/Object;)V")
+    @Bridge("m(Ljava/lang/Number;)V")
+    interface C extends A<Integer>, B<Integer> {
+        void m(Integer i);
+    }
+
+    @Bridge("m(Ljava/lang/Object;)V")
+    @Bridge("m(Ljava/lang/Number;)V")
+    static abstract class D implements A<Integer>, B<Integer> {
+        public abstract void m(Integer i);
+    }
+
+    @Bridge("m(Ljava/lang/Object;)V")
+    @Bridge("m(Ljava/lang/Number;)V")
+    static class E implements A<Integer>, B<Integer> {
+        public void m(Integer i) { }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/generics/bridges/tests/TestNoBridgeInSiblingsSuper.java	Thu Apr 18 10:33:07 2013 +0100
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+class TestNoBridgeInSiblingSuper {
+    interface A { Object m(); }    
+    interface B { String m(); }
+    //no bridge here!
+    interface C extends A, B { }
+    
+    @Bridge("m()Ljava/lang/Object;")
+    interface D extends C {
+        String m();
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/generics/bridges/tests/TestNoDuplicateBridges01.java	Thu Apr 18 10:33:07 2013 +0100
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+class TestNoDuplicateBridges01 {
+    interface A1 { Object m(); }
+    interface A2 { Object m(); }
+    
+    @Bridge("m()Ljava/lang/Object;")
+    interface B extends A1, A2 { B m(); }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/generics/bridges/tests/TestNoDuplicateBridges02.java	Thu Apr 18 10:33:07 2013 +0100
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+class TestNoDuplicateBridges02 {
+    interface A<T> {
+        A<T> get();
+    }
+
+    @Bridge("get()LTestNoDuplicateBridges02$A;")
+    interface B<T> extends A<T> {
+        B<T> get();
+    }
+
+    @Bridge("get()LTestNoDuplicateBridges02$A;")
+    @Bridge("get()LTestNoDuplicateBridges02$B;")
+    interface C<T> extends A<T>, B<T> {
+        C<T> get();
+    }
+}