# HG changeset patch # User mcimadamore # Date 1515775798 0 # Node ID a5f815d1060bc4b5173d3e384e6c09f90b4b04ae # Parent 7f57c5908c579b33b7b500165718641d0aa23833 8194932: no ambuguity error is emitted if classfile contains two identical methods with different return types Summary: add recovery logic when classfile contains two signature-equivalent methods Reviewed-by: jlahoda, vromero diff -r 7f57c5908c57 -r a5f815d1060b src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java Fri Jan 12 10:33:06 2018 +0100 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java Fri Jan 12 16:49:58 2018 +0000 @@ -3464,6 +3464,7 @@ types.hasSameArgs(sym.type, byName.type) || types.hasSameArgs(types.erasure(sym.type), types.erasure(byName.type)))) { if ((sym.flags() & VARARGS) != (byName.flags() & VARARGS)) { + sym.flags_field |= CLASH; varargsDuplicateError(pos, sym, byName); return true; } else if (sym.kind == MTH && !types.hasSameArgs(sym.type, byName.type, false)) { diff -r 7f57c5908c57 -r a5f815d1060b src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java Fri Jan 12 10:33:06 2018 +0100 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java Fri Jan 12 16:49:58 2018 +0000 @@ -1618,19 +1618,30 @@ if ((m1.flags() & BRIDGE) != (m2.flags() & BRIDGE)) return ((m1.flags() & BRIDGE) != 0) ? m2 : m1; + if (m1.baseSymbol() == m2.baseSymbol()) { + // this is the same imported symbol which has been cloned twice. + // Return the first one (either will do). + return m1; + } + // if one overrides or hides the other, use it TypeSymbol m1Owner = (TypeSymbol)m1.owner; TypeSymbol m2Owner = (TypeSymbol)m2.owner; - if (types.asSuper(m1Owner.type, m2Owner) != null && - ((m1.owner.flags_field & INTERFACE) == 0 || - (m2.owner.flags_field & INTERFACE) != 0) && - m1.overrides(m2, m1Owner, types, false)) - return m1; - if (types.asSuper(m2Owner.type, m1Owner) != null && - ((m2.owner.flags_field & INTERFACE) == 0 || - (m1.owner.flags_field & INTERFACE) != 0) && - m2.overrides(m1, m2Owner, types, false)) - return m2; + // the two owners can never be the same if the target methods are compiled from source, + // but we need to protect against cases where the methods are defined in some classfile + // and make sure we issue an ambiguity error accordingly (by skipping the logic below). + if (m1Owner != m2Owner) { + if (types.asSuper(m1Owner.type, m2Owner) != null && + ((m1.owner.flags_field & INTERFACE) == 0 || + (m2.owner.flags_field & INTERFACE) != 0) && + m1.overrides(m2, m1Owner, types, false)) + return m1; + if (types.asSuper(m2Owner.type, m1Owner) != null && + ((m2.owner.flags_field & INTERFACE) == 0 || + (m1.owner.flags_field & INTERFACE) != 0) && + m2.overrides(m1, m2Owner, types, false)) + return m2; + } boolean m1Abstract = (m1.flags() & ABSTRACT) != 0; boolean m2Abstract = (m2.flags() & ABSTRACT) != 0; if (m1Abstract && !m2Abstract) return m2; diff -r 7f57c5908c57 -r a5f815d1060b test/langtools/tools/javac/8194932/Foo.jcod --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/langtools/tools/javac/8194932/Foo.jcod Fri Jan 12 16:49:58 2018 +0000 @@ -0,0 +1,115 @@ +class Foo { + 0xCAFEBABE; + 0; // minor version + 52; // version + [] { // Constant Pool + ; // first element is empty + Method #4 #14; // #1 + String #15; // #2 + class #16; // #3 + class #17; // #4 + Utf8 ""; // #5 + Utf8 "()V"; // #6 + Utf8 "Code"; // #7 + Utf8 "LineNumberTable"; // #8 + Utf8 "m"; // #9 + Utf8 "m2"; // #10 + Utf8 "()Ljava/lang/String;"; // #11 + Utf8 "SourceFile"; // #12 + Utf8 "Foo.java"; // #13 + NameAndType #5 #6; // #14 + Utf8 "Hello"; // #15 + Utf8 "Foo"; // #16 + Utf8 "java/lang/Object"; // #17 + } // Constant Pool + + 0x0020; // access + #3;// this_cpx + #4;// super_cpx + + [] { // Interfaces + } // Interfaces + + [] { // fields + } // fields + + [] { // methods + { // Member + 0x0000; // access + #5; // name_cpx + #6; // sig_cpx + [] { // Attributes + Attr(#7) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x2AB70001B1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#8) { // LineNumberTable + [] { // LineNumberTable + 0 1; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member + 0x0000; // access + #9; // name_cpx + #6; // sig_cpx + [] { // Attributes + Attr(#7) { // Code + 0; // max_stack + 1; // max_locals + Bytes[]{ + 0xB1; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#8) { // LineNumberTable + [] { // LineNumberTable + 0 2; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + ; + { // Member + 0x0000; // access + #9; // name_cpx + #11; // sig_cpx + [] { // Attributes + Attr(#7) { // Code + 1; // max_stack + 1; // max_locals + Bytes[]{ + 0x1202B0; + }; + [] { // Traps + } // end Traps + [] { // Attributes + Attr(#8) { // LineNumberTable + [] { // LineNumberTable + 0 3; + } + } // end LineNumberTable + } // Attributes + } // end Code + } // Attributes + } // Member + } // methods + + [] { // Attributes + Attr(#12) { // SourceFile + #13; + } // end SourceFile + } // Attributes +} // end class Foo diff -r 7f57c5908c57 -r a5f815d1060b test/langtools/tools/javac/8194932/T8194932.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/langtools/tools/javac/8194932/T8194932.java Fri Jan 12 16:49:58 2018 +0000 @@ -0,0 +1,13 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8194932 + * @summary no ambuguity error is emitted if classfile contains two identical methods with different return types + * @build Foo + * @compile/fail/ref=T8194932.out -XDrawDiagnostics T8194932.java + */ + +class T8194932 { + void test(Foo foo) { + foo.m(); //should get an ambiguity here + } +} diff -r 7f57c5908c57 -r a5f815d1060b test/langtools/tools/javac/8194932/T8194932.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/langtools/tools/javac/8194932/T8194932.out Fri Jan 12 16:49:58 2018 +0000 @@ -0,0 +1,2 @@ +T8194932.java:11:12: compiler.err.ref.ambiguous: m, kindname.method, m(), Foo, kindname.method, m(), Foo +1 error