Fri, 28 Jan 2011 12:01:07 +0000
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
1.1 --- a/src/share/classes/com/sun/tools/javac/code/Flags.java Fri Jan 28 00:09:38 2011 -0800 1.2 +++ b/src/share/classes/com/sun/tools/javac/code/Flags.java Fri Jan 28 12:01:07 2011 +0000 1.3 @@ -1,5 +1,5 @@ 1.4 /* 1.5 - * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. 1.6 + * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved. 1.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.8 * 1.9 * This code is free software; you can redistribute it and/or modify it 1.10 @@ -252,6 +252,11 @@ 1.11 */ 1.12 public static final long EFFECTIVELY_FINAL = 1L<<42; 1.13 1.14 + /** 1.15 + * Flag that marks non-override equivalent methods with the same signature 1.16 + */ 1.17 + public static final long CLASH = 1L<<43; 1.18 + 1.19 /** Modifier masks. 1.20 */ 1.21 public static final int
2.1 --- a/src/share/classes/com/sun/tools/javac/comp/Check.java Fri Jan 28 00:09:38 2011 -0800 2.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Check.java Fri Jan 28 12:01:07 2011 +0000 2.3 @@ -2121,7 +2121,7 @@ 2.4 2.5 public boolean accepts(Symbol s) { 2.6 return s.kind == MTH && 2.7 - (s.flags() & SYNTHETIC) == 0 && 2.8 + (s.flags() & (SYNTHETIC | CLASH)) == 0 && 2.9 s.isInheritedIn(site.tsym, types) && 2.10 !s.isConstructor(); 2.11 } 2.12 @@ -2581,28 +2581,42 @@ 2.13 if (sym.owner.name == names.any) return false; 2.14 for (Scope.Entry e = s.lookup(sym.name); e.scope == s; e = e.next()) { 2.15 if (sym != e.sym && 2.16 + (e.sym.flags() & CLASH) == 0 && 2.17 sym.kind == e.sym.kind && 2.18 sym.name != names.error && 2.19 (sym.kind != MTH || types.hasSameArgs(types.erasure(sym.type), types.erasure(e.sym.type)))) { 2.20 - if ((sym.flags() & VARARGS) != (e.sym.flags() & VARARGS)) 2.21 + if ((sym.flags() & VARARGS) != (e.sym.flags() & VARARGS)) { 2.22 varargsDuplicateError(pos, sym, e.sym); 2.23 - else if (sym.kind == MTH && !types.overrideEquivalent(sym.type, e.sym.type)) 2.24 + return true; 2.25 + } else if (sym.kind == MTH && !hasSameSignature(sym.type, e.sym.type)) { 2.26 duplicateErasureError(pos, sym, e.sym); 2.27 - else 2.28 + sym.flags_field |= CLASH; 2.29 + return true; 2.30 + } else { 2.31 duplicateError(pos, e.sym); 2.32 - return false; 2.33 + return false; 2.34 + } 2.35 } 2.36 } 2.37 return true; 2.38 } 2.39 //where 2.40 - /** Report duplicate declaration error. 2.41 - */ 2.42 - void duplicateErasureError(DiagnosticPosition pos, Symbol sym1, Symbol sym2) { 2.43 - if (!sym1.type.isErroneous() && !sym2.type.isErroneous()) { 2.44 - log.error(pos, "name.clash.same.erasure", sym1, sym2); 2.45 + boolean hasSameSignature(Type mt1, Type mt2) { 2.46 + if (mt1.tag == FORALL && mt2.tag == FORALL) { 2.47 + ForAll fa1 = (ForAll)mt1; 2.48 + ForAll fa2 = (ForAll)mt2; 2.49 + mt2 = types.subst(fa2, fa2.tvars, fa1.tvars); 2.50 + } 2.51 + return types.hasSameArgs(mt1.asMethodType(), mt2.asMethodType()); 2.52 } 2.53 - } 2.54 + 2.55 + /** Report duplicate declaration error. 2.56 + */ 2.57 + void duplicateErasureError(DiagnosticPosition pos, Symbol sym1, Symbol sym2) { 2.58 + if (!sym1.type.isErroneous() && !sym2.type.isErroneous()) { 2.59 + log.error(pos, "name.clash.same.erasure", sym1, sym2); 2.60 + } 2.61 + } 2.62 2.63 /** Check that single-type import is not already imported or top-level defined, 2.64 * but make an exception for two single-type imports which denote the same type.
3.1 --- a/src/share/classes/com/sun/tools/javac/comp/Resolve.java Fri Jan 28 00:09:38 2011 -0800 3.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Resolve.java Fri Jan 28 12:01:07 2011 +0000 3.3 @@ -278,7 +278,7 @@ 3.4 return true; 3.5 else { 3.6 Symbol s2 = ((MethodSymbol)sym).implementation(site.tsym, types, true); 3.7 - return (s2 == null || s2 == sym || 3.8 + return (s2 == null || s2 == sym || sym.owner == s2.owner || 3.9 s2.isPolymorphicSignatureGeneric() || 3.10 !types.isSubSignature(types.memberType(site, s2), types.memberType(site, sym))); 3.11 } 3.12 @@ -712,13 +712,14 @@ 3.13 Type mt1 = types.memberType(site, m1); 3.14 Type mt2 = types.memberType(site, m2); 3.15 if (!types.overrideEquivalent(mt1, mt2)) 3.16 - return new AmbiguityError(m1, m2); 3.17 + return ambiguityError(m1, m2); 3.18 + 3.19 // same signature; select (a) the non-bridge method, or 3.20 // (b) the one that overrides the other, or (c) the concrete 3.21 // one, or (d) merge both abstract signatures 3.22 - if ((m1.flags() & BRIDGE) != (m2.flags() & BRIDGE)) { 3.23 + if ((m1.flags() & BRIDGE) != (m2.flags() & BRIDGE)) 3.24 return ((m1.flags() & BRIDGE) != 0) ? m2 : m1; 3.25 - } 3.26 + 3.27 // if one overrides or hides the other, use it 3.28 TypeSymbol m1Owner = (TypeSymbol)m1.owner; 3.29 TypeSymbol m2Owner = (TypeSymbol)m2.owner; 3.30 @@ -738,24 +739,24 @@ 3.31 if (m2Abstract && !m1Abstract) return m1; 3.32 // both abstract or both concrete 3.33 if (!m1Abstract && !m2Abstract) 3.34 - return new AmbiguityError(m1, m2); 3.35 + return ambiguityError(m1, m2); 3.36 // check that both signatures have the same erasure 3.37 if (!types.isSameTypes(m1.erasure(types).getParameterTypes(), 3.38 m2.erasure(types).getParameterTypes())) 3.39 - return new AmbiguityError(m1, m2); 3.40 + return ambiguityError(m1, m2); 3.41 // both abstract, neither overridden; merge throws clause and result type 3.42 Symbol mostSpecific; 3.43 Type result2 = mt2.getReturnType(); 3.44 if (mt2.tag == FORALL) 3.45 result2 = types.subst(result2, ((ForAll)mt2).tvars, ((ForAll)mt1).tvars); 3.46 - if (types.isSubtype(mt1.getReturnType(), result2)) { 3.47 + if (types.isSubtype(mt1.getReturnType(), result2)) 3.48 mostSpecific = m1; 3.49 - } else if (types.isSubtype(result2, mt1.getReturnType())) { 3.50 + else if (types.isSubtype(result2, mt1.getReturnType())) 3.51 mostSpecific = m2; 3.52 - } else { 3.53 + else { 3.54 // Theoretically, this can't happen, but it is possible 3.55 // due to error recovery or mixing incompatible class files 3.56 - return new AmbiguityError(m1, m2); 3.57 + return ambiguityError(m1, m2); 3.58 } 3.59 MethodSymbol result = new MethodSymbol( 3.60 mostSpecific.flags(), 3.61 @@ -777,7 +778,7 @@ 3.62 } 3.63 if (m1SignatureMoreSpecific) return m1; 3.64 if (m2SignatureMoreSpecific) return m2; 3.65 - return new AmbiguityError(m1, m2); 3.66 + return ambiguityError(m1, m2); 3.67 case AMBIGUOUS: 3.68 AmbiguityError e = (AmbiguityError)m2; 3.69 Symbol err1 = mostSpecific(m1, e.sym, env, site, allowBoxing, useVarargs); 3.70 @@ -787,9 +788,9 @@ 3.71 if (err1 instanceof AmbiguityError && 3.72 err2 instanceof AmbiguityError && 3.73 ((AmbiguityError)err1).sym == ((AmbiguityError)err2).sym) 3.74 - return new AmbiguityError(m1, m2); 3.75 + return ambiguityError(m1, m2); 3.76 else 3.77 - return new AmbiguityError(err1, err2); 3.78 + return ambiguityError(err1, err2); 3.79 default: 3.80 throw new AssertionError(); 3.81 } 3.82 @@ -844,6 +845,14 @@ 3.83 return to; 3.84 } 3.85 } 3.86 + //where 3.87 + Symbol ambiguityError(Symbol m1, Symbol m2) { 3.88 + if (((m1.flags() | m2.flags()) & CLASH) != 0) { 3.89 + return (m1.flags() & CLASH) == 0 ? m1 : m2; 3.90 + } else { 3.91 + return new AmbiguityError(m1, m2); 3.92 + } 3.93 + } 3.94 3.95 /** Find best qualified method matching given name, type and value 3.96 * arguments.
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 4.2 +++ b/test/tools/javac/generics/6910550/T6910550a.java Fri Jan 28 12:01:07 2011 +0000 4.3 @@ -0,0 +1,16 @@ 4.4 +/* 4.5 + * @test /nodynamiccopyright/ 4.6 + * @bug 6910550 4.7 + * 4.8 + * @summary javac 1.5.0_17 fails with incorrect error message 4.9 + * @compile/fail/ref=T6910550a.out -XDrawDiagnostics T6910550a.java 4.10 + * 4.11 + */ 4.12 +import java.util.*; 4.13 + 4.14 +class T6910550a { 4.15 + void m(List<String> ls) {} 4.16 + void m(List<Integer> li) {} 4.17 + 4.18 + { m(Arrays.asList(12)); } 4.19 +}
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 5.2 +++ b/test/tools/javac/generics/6910550/T6910550a.out Fri Jan 28 12:01:07 2011 +0000 5.3 @@ -0,0 +1,2 @@ 5.4 +T6910550a.java:13:10: compiler.err.name.clash.same.erasure: m(java.util.List<java.lang.Integer>), m(java.util.List<java.lang.String>) 5.5 +1 error
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 6.2 +++ b/test/tools/javac/generics/6910550/T6910550b.java Fri Jan 28 12:01:07 2011 +0000 6.3 @@ -0,0 +1,16 @@ 6.4 +/* 6.5 + * @test /nodynamiccopyright/ 6.6 + * @bug 6910550 6.7 + * 6.8 + * @summary javac 1.5.0_17 fails with incorrect error message 6.9 + * @compile/fail/ref=T6910550b.out -XDrawDiagnostics T6910550b.java 6.10 + * 6.11 + */ 6.12 + 6.13 +class T6910550b<X, Y, Z> { 6.14 + void m(X x) {} 6.15 + void m(Y y) {} 6.16 + void m(Z y) {} 6.17 + 6.18 + { m(null); } 6.19 +}
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 7.2 +++ b/test/tools/javac/generics/6910550/T6910550b.out Fri Jan 28 12:01:07 2011 +0000 7.3 @@ -0,0 +1,3 @@ 7.4 +T6910550b.java:12:10: compiler.err.name.clash.same.erasure: m(Y), m(X) 7.5 +T6910550b.java:13:10: compiler.err.name.clash.same.erasure: m(Z), m(X) 7.6 +2 errors
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 8.2 +++ b/test/tools/javac/generics/6910550/T6910550c.java Fri Jan 28 12:01:07 2011 +0000 8.3 @@ -0,0 +1,18 @@ 8.4 +/* 8.5 + * @test /nodynamiccopyright/ 8.6 + * @bug 6910550 8.7 + * 8.8 + * @summary javac 1.5.0_17 fails with incorrect error message 8.9 + * @compile/fail/ref=T6910550c.out -XDrawDiagnostics T6910550c.java 8.10 + * 8.11 + */ 8.12 + 8.13 +class T6910550c { 8.14 + void m(Object[] x) {} 8.15 + void m(Object... x) {} 8.16 + 8.17 + { m(); } 8.18 + { m(null); } 8.19 + { m(null, null); } 8.20 + { m(null, null, null); } 8.21 +}
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 9.2 +++ b/test/tools/javac/generics/6910550/T6910550c.out Fri Jan 28 12:01:07 2011 +0000 9.3 @@ -0,0 +1,2 @@ 9.4 +T6910550c.java:12:10: compiler.err.array.and.varargs: m(java.lang.Object...), m(java.lang.Object[]), T6910550c 9.5 +1 error
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 10.2 +++ b/test/tools/javac/generics/6910550/T6910550d.java Fri Jan 28 12:01:07 2011 +0000 10.3 @@ -0,0 +1,15 @@ 10.4 +/* 10.5 + * @test /nodynamiccopyright/ 10.6 + * @bug 6910550 10.7 + * 10.8 + * @summary javac 1.5.0_17 fails with incorrect error message 10.9 + * @compile/fail/ref=T6910550d.out -XDrawDiagnostics T6910550d.java 10.10 + * 10.11 + */ 10.12 + 10.13 +class T6910550d { 10.14 + <X> void m(X x) {} 10.15 + <Y> void m(Y y) {} 10.16 + 10.17 + { m(null); } 10.18 +}
11.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 11.2 +++ b/test/tools/javac/generics/6910550/T6910550d.out Fri Jan 28 12:01:07 2011 +0000 11.3 @@ -0,0 +1,2 @@ 11.4 +T6910550d.java:12:14: compiler.err.already.defined: <X>m(X), T6910550d 11.5 +1 error
12.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 12.2 +++ b/test/tools/javac/generics/6910550/T6910550e.java Fri Jan 28 12:01:07 2011 +0000 12.3 @@ -0,0 +1,18 @@ 12.4 +/* 12.5 + * @test /nodynamiccopyright/ 12.6 + * @bug 6910550 12.7 + * 12.8 + * @summary javac 1.5.0_17 fails with incorrect error message 12.9 + * @compile/fail/ref=T6910550e.out -XDrawDiagnostics T6910550e.java 12.10 + * 12.11 + */ 12.12 + 12.13 +class T6910550e { 12.14 + static class Pair<X,Y> {} 12.15 + 12.16 + <X> void m(Pair<X,X> x) {} 12.17 + <X,Y> void m(Pair<X,Y> y) {} 12.18 + 12.19 + { m(new Pair<String,String>()); 12.20 + m(new Pair<String,Integer>()); } 12.21 +}
13.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 13.2 +++ b/test/tools/javac/generics/6910550/T6910550e.out Fri Jan 28 12:01:07 2011 +0000 13.3 @@ -0,0 +1,2 @@ 13.4 +T6910550e.java:14:16: compiler.err.name.clash.same.erasure: <X,Y>m(T6910550e.Pair<X,Y>), <X>m(T6910550e.Pair<X,X>) 13.5 +1 error