# HG changeset patch # User mcimadamore # Date 1296216067 0 # Node ID 2088e674f0e0f4ead2a91bd5473e608ea4795964 # Parent 92ab09ed59fde986322b8057d8bc238a0e084ba0 6910550: javac 1.5.0_17 fails with incorrect error message Summary: multiple clashing members declared in same class should be added to the class' scope in order to avoid downstream spurious diagnostics Reviewed-by: jjg diff -r 92ab09ed59fd -r 2088e674f0e0 src/share/classes/com/sun/tools/javac/code/Flags.java --- a/src/share/classes/com/sun/tools/javac/code/Flags.java Fri Jan 28 00:09:38 2011 -0800 +++ b/src/share/classes/com/sun/tools/javac/code/Flags.java Fri Jan 28 12:01:07 2011 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2011, 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 @@ -252,6 +252,11 @@ */ public static final long EFFECTIVELY_FINAL = 1L<<42; + /** + * Flag that marks non-override equivalent methods with the same signature + */ + public static final long CLASH = 1L<<43; + /** Modifier masks. */ public static final int diff -r 92ab09ed59fd -r 2088e674f0e0 src/share/classes/com/sun/tools/javac/comp/Check.java --- a/src/share/classes/com/sun/tools/javac/comp/Check.java Fri Jan 28 00:09:38 2011 -0800 +++ b/src/share/classes/com/sun/tools/javac/comp/Check.java Fri Jan 28 12:01:07 2011 +0000 @@ -2121,7 +2121,7 @@ public boolean accepts(Symbol s) { return s.kind == MTH && - (s.flags() & SYNTHETIC) == 0 && + (s.flags() & (SYNTHETIC | CLASH)) == 0 && s.isInheritedIn(site.tsym, types) && !s.isConstructor(); } @@ -2581,28 +2581,42 @@ if (sym.owner.name == names.any) return false; for (Scope.Entry e = s.lookup(sym.name); e.scope == s; e = e.next()) { if (sym != e.sym && + (e.sym.flags() & CLASH) == 0 && sym.kind == e.sym.kind && sym.name != names.error && (sym.kind != MTH || types.hasSameArgs(types.erasure(sym.type), types.erasure(e.sym.type)))) { - if ((sym.flags() & VARARGS) != (e.sym.flags() & VARARGS)) + if ((sym.flags() & VARARGS) != (e.sym.flags() & VARARGS)) { varargsDuplicateError(pos, sym, e.sym); - else if (sym.kind == MTH && !types.overrideEquivalent(sym.type, e.sym.type)) + return true; + } else if (sym.kind == MTH && !hasSameSignature(sym.type, e.sym.type)) { duplicateErasureError(pos, sym, e.sym); - else + sym.flags_field |= CLASH; + return true; + } else { duplicateError(pos, e.sym); - return false; + return false; + } } } return true; } //where - /** Report duplicate declaration error. - */ - void duplicateErasureError(DiagnosticPosition pos, Symbol sym1, Symbol sym2) { - if (!sym1.type.isErroneous() && !sym2.type.isErroneous()) { - log.error(pos, "name.clash.same.erasure", sym1, sym2); + boolean hasSameSignature(Type mt1, Type mt2) { + if (mt1.tag == FORALL && mt2.tag == FORALL) { + ForAll fa1 = (ForAll)mt1; + ForAll fa2 = (ForAll)mt2; + mt2 = types.subst(fa2, fa2.tvars, fa1.tvars); + } + return types.hasSameArgs(mt1.asMethodType(), mt2.asMethodType()); } - } + + /** Report duplicate declaration error. + */ + void duplicateErasureError(DiagnosticPosition pos, Symbol sym1, Symbol sym2) { + if (!sym1.type.isErroneous() && !sym2.type.isErroneous()) { + log.error(pos, "name.clash.same.erasure", sym1, sym2); + } + } /** Check that single-type import is not already imported or top-level defined, * but make an exception for two single-type imports which denote the same type. diff -r 92ab09ed59fd -r 2088e674f0e0 src/share/classes/com/sun/tools/javac/comp/Resolve.java --- a/src/share/classes/com/sun/tools/javac/comp/Resolve.java Fri Jan 28 00:09:38 2011 -0800 +++ b/src/share/classes/com/sun/tools/javac/comp/Resolve.java Fri Jan 28 12:01:07 2011 +0000 @@ -278,7 +278,7 @@ return true; else { Symbol s2 = ((MethodSymbol)sym).implementation(site.tsym, types, true); - return (s2 == null || s2 == sym || + return (s2 == null || s2 == sym || sym.owner == s2.owner || s2.isPolymorphicSignatureGeneric() || !types.isSubSignature(types.memberType(site, s2), types.memberType(site, sym))); } @@ -712,13 +712,14 @@ Type mt1 = types.memberType(site, m1); Type mt2 = types.memberType(site, m2); if (!types.overrideEquivalent(mt1, mt2)) - return new AmbiguityError(m1, m2); + return ambiguityError(m1, m2); + // same signature; select (a) the non-bridge method, or // (b) the one that overrides the other, or (c) the concrete // one, or (d) merge both abstract signatures - if ((m1.flags() & BRIDGE) != (m2.flags() & BRIDGE)) { + if ((m1.flags() & BRIDGE) != (m2.flags() & BRIDGE)) return ((m1.flags() & BRIDGE) != 0) ? m2 : m1; - } + // if one overrides or hides the other, use it TypeSymbol m1Owner = (TypeSymbol)m1.owner; TypeSymbol m2Owner = (TypeSymbol)m2.owner; @@ -738,24 +739,24 @@ if (m2Abstract && !m1Abstract) return m1; // both abstract or both concrete if (!m1Abstract && !m2Abstract) - return new AmbiguityError(m1, m2); + return ambiguityError(m1, m2); // check that both signatures have the same erasure if (!types.isSameTypes(m1.erasure(types).getParameterTypes(), m2.erasure(types).getParameterTypes())) - return new AmbiguityError(m1, m2); + return ambiguityError(m1, m2); // both abstract, neither overridden; merge throws clause and result type Symbol mostSpecific; Type result2 = mt2.getReturnType(); if (mt2.tag == FORALL) result2 = types.subst(result2, ((ForAll)mt2).tvars, ((ForAll)mt1).tvars); - if (types.isSubtype(mt1.getReturnType(), result2)) { + if (types.isSubtype(mt1.getReturnType(), result2)) mostSpecific = m1; - } else if (types.isSubtype(result2, mt1.getReturnType())) { + else if (types.isSubtype(result2, mt1.getReturnType())) mostSpecific = m2; - } else { + else { // Theoretically, this can't happen, but it is possible // due to error recovery or mixing incompatible class files - return new AmbiguityError(m1, m2); + return ambiguityError(m1, m2); } MethodSymbol result = new MethodSymbol( mostSpecific.flags(), @@ -777,7 +778,7 @@ } if (m1SignatureMoreSpecific) return m1; if (m2SignatureMoreSpecific) return m2; - return new AmbiguityError(m1, m2); + return ambiguityError(m1, m2); case AMBIGUOUS: AmbiguityError e = (AmbiguityError)m2; Symbol err1 = mostSpecific(m1, e.sym, env, site, allowBoxing, useVarargs); @@ -787,9 +788,9 @@ if (err1 instanceof AmbiguityError && err2 instanceof AmbiguityError && ((AmbiguityError)err1).sym == ((AmbiguityError)err2).sym) - return new AmbiguityError(m1, m2); + return ambiguityError(m1, m2); else - return new AmbiguityError(err1, err2); + return ambiguityError(err1, err2); default: throw new AssertionError(); } @@ -844,6 +845,14 @@ return to; } } + //where + Symbol ambiguityError(Symbol m1, Symbol m2) { + if (((m1.flags() | m2.flags()) & CLASH) != 0) { + return (m1.flags() & CLASH) == 0 ? m1 : m2; + } else { + return new AmbiguityError(m1, m2); + } + } /** Find best qualified method matching given name, type and value * arguments. diff -r 92ab09ed59fd -r 2088e674f0e0 test/tools/javac/generics/6910550/T6910550a.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/generics/6910550/T6910550a.java Fri Jan 28 12:01:07 2011 +0000 @@ -0,0 +1,16 @@ +/* + * @test /nodynamiccopyright/ + * @bug 6910550 + * + * @summary javac 1.5.0_17 fails with incorrect error message + * @compile/fail/ref=T6910550a.out -XDrawDiagnostics T6910550a.java + * + */ +import java.util.*; + +class T6910550a { + void m(List ls) {} + void m(List li) {} + + { m(Arrays.asList(12)); } +} diff -r 92ab09ed59fd -r 2088e674f0e0 test/tools/javac/generics/6910550/T6910550a.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/generics/6910550/T6910550a.out Fri Jan 28 12:01:07 2011 +0000 @@ -0,0 +1,2 @@ +T6910550a.java:13:10: compiler.err.name.clash.same.erasure: m(java.util.List), m(java.util.List) +1 error diff -r 92ab09ed59fd -r 2088e674f0e0 test/tools/javac/generics/6910550/T6910550b.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/generics/6910550/T6910550b.java Fri Jan 28 12:01:07 2011 +0000 @@ -0,0 +1,16 @@ +/* + * @test /nodynamiccopyright/ + * @bug 6910550 + * + * @summary javac 1.5.0_17 fails with incorrect error message + * @compile/fail/ref=T6910550b.out -XDrawDiagnostics T6910550b.java + * + */ + +class T6910550b { + void m(X x) {} + void m(Y y) {} + void m(Z y) {} + + { m(null); } +} diff -r 92ab09ed59fd -r 2088e674f0e0 test/tools/javac/generics/6910550/T6910550b.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/generics/6910550/T6910550b.out Fri Jan 28 12:01:07 2011 +0000 @@ -0,0 +1,3 @@ +T6910550b.java:12:10: compiler.err.name.clash.same.erasure: m(Y), m(X) +T6910550b.java:13:10: compiler.err.name.clash.same.erasure: m(Z), m(X) +2 errors diff -r 92ab09ed59fd -r 2088e674f0e0 test/tools/javac/generics/6910550/T6910550c.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/generics/6910550/T6910550c.java Fri Jan 28 12:01:07 2011 +0000 @@ -0,0 +1,18 @@ +/* + * @test /nodynamiccopyright/ + * @bug 6910550 + * + * @summary javac 1.5.0_17 fails with incorrect error message + * @compile/fail/ref=T6910550c.out -XDrawDiagnostics T6910550c.java + * + */ + +class T6910550c { + void m(Object[] x) {} + void m(Object... x) {} + + { m(); } + { m(null); } + { m(null, null); } + { m(null, null, null); } +} diff -r 92ab09ed59fd -r 2088e674f0e0 test/tools/javac/generics/6910550/T6910550c.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/generics/6910550/T6910550c.out Fri Jan 28 12:01:07 2011 +0000 @@ -0,0 +1,2 @@ +T6910550c.java:12:10: compiler.err.array.and.varargs: m(java.lang.Object...), m(java.lang.Object[]), T6910550c +1 error diff -r 92ab09ed59fd -r 2088e674f0e0 test/tools/javac/generics/6910550/T6910550d.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/generics/6910550/T6910550d.java Fri Jan 28 12:01:07 2011 +0000 @@ -0,0 +1,15 @@ +/* + * @test /nodynamiccopyright/ + * @bug 6910550 + * + * @summary javac 1.5.0_17 fails with incorrect error message + * @compile/fail/ref=T6910550d.out -XDrawDiagnostics T6910550d.java + * + */ + +class T6910550d { + void m(X x) {} + void m(Y y) {} + + { m(null); } +} diff -r 92ab09ed59fd -r 2088e674f0e0 test/tools/javac/generics/6910550/T6910550d.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/generics/6910550/T6910550d.out Fri Jan 28 12:01:07 2011 +0000 @@ -0,0 +1,2 @@ +T6910550d.java:12:14: compiler.err.already.defined: m(X), T6910550d +1 error diff -r 92ab09ed59fd -r 2088e674f0e0 test/tools/javac/generics/6910550/T6910550e.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/generics/6910550/T6910550e.java Fri Jan 28 12:01:07 2011 +0000 @@ -0,0 +1,18 @@ +/* + * @test /nodynamiccopyright/ + * @bug 6910550 + * + * @summary javac 1.5.0_17 fails with incorrect error message + * @compile/fail/ref=T6910550e.out -XDrawDiagnostics T6910550e.java + * + */ + +class T6910550e { + static class Pair {} + + void m(Pair x) {} + void m(Pair y) {} + + { m(new Pair()); + m(new Pair()); } +} diff -r 92ab09ed59fd -r 2088e674f0e0 test/tools/javac/generics/6910550/T6910550e.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/generics/6910550/T6910550e.out Fri Jan 28 12:01:07 2011 +0000 @@ -0,0 +1,2 @@ +T6910550e.java:14:16: compiler.err.name.clash.same.erasure: m(T6910550e.Pair), m(T6910550e.Pair) +1 error