提交 571d946b 编写于 作者: M mcimadamore

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
上级 64f8eda3
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -252,6 +252,11 @@ public class Flags { ...@@ -252,6 +252,11 @@ public class Flags {
*/ */
public static final long EFFECTIVELY_FINAL = 1L<<42; 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. /** Modifier masks.
*/ */
public static final int public static final int
......
...@@ -2121,7 +2121,7 @@ public class Check { ...@@ -2121,7 +2121,7 @@ public class Check {
public boolean accepts(Symbol s) { public boolean accepts(Symbol s) {
return s.kind == MTH && return s.kind == MTH &&
(s.flags() & SYNTHETIC) == 0 && (s.flags() & (SYNTHETIC | CLASH)) == 0 &&
s.isInheritedIn(site.tsym, types) && s.isInheritedIn(site.tsym, types) &&
!s.isConstructor(); !s.isConstructor();
} }
...@@ -2581,21 +2581,35 @@ public class Check { ...@@ -2581,21 +2581,35 @@ public class Check {
if (sym.owner.name == names.any) return false; if (sym.owner.name == names.any) return false;
for (Scope.Entry e = s.lookup(sym.name); e.scope == s; e = e.next()) { for (Scope.Entry e = s.lookup(sym.name); e.scope == s; e = e.next()) {
if (sym != e.sym && if (sym != e.sym &&
(e.sym.flags() & CLASH) == 0 &&
sym.kind == e.sym.kind && sym.kind == e.sym.kind &&
sym.name != names.error && sym.name != names.error &&
(sym.kind != MTH || types.hasSameArgs(types.erasure(sym.type), types.erasure(e.sym.type)))) { (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); 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); duplicateErasureError(pos, sym, e.sym);
else sym.flags_field |= CLASH;
return true;
} else {
duplicateError(pos, e.sym); duplicateError(pos, e.sym);
return false; return false;
} }
} }
}
return true; return true;
} }
//where //where
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. /** Report duplicate declaration error.
*/ */
void duplicateErasureError(DiagnosticPosition pos, Symbol sym1, Symbol sym2) { void duplicateErasureError(DiagnosticPosition pos, Symbol sym1, Symbol sym2) {
......
...@@ -278,7 +278,7 @@ public class Resolve { ...@@ -278,7 +278,7 @@ public class Resolve {
return true; return true;
else { else {
Symbol s2 = ((MethodSymbol)sym).implementation(site.tsym, types, true); 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() || s2.isPolymorphicSignatureGeneric() ||
!types.isSubSignature(types.memberType(site, s2), types.memberType(site, sym))); !types.isSubSignature(types.memberType(site, s2), types.memberType(site, sym)));
} }
...@@ -712,13 +712,14 @@ public class Resolve { ...@@ -712,13 +712,14 @@ public class Resolve {
Type mt1 = types.memberType(site, m1); Type mt1 = types.memberType(site, m1);
Type mt2 = types.memberType(site, m2); Type mt2 = types.memberType(site, m2);
if (!types.overrideEquivalent(mt1, mt2)) if (!types.overrideEquivalent(mt1, mt2))
return new AmbiguityError(m1, m2); return ambiguityError(m1, m2);
// same signature; select (a) the non-bridge method, or // same signature; select (a) the non-bridge method, or
// (b) the one that overrides the other, or (c) the concrete // (b) the one that overrides the other, or (c) the concrete
// one, or (d) merge both abstract signatures // 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; return ((m1.flags() & BRIDGE) != 0) ? m2 : m1;
}
// if one overrides or hides the other, use it // if one overrides or hides the other, use it
TypeSymbol m1Owner = (TypeSymbol)m1.owner; TypeSymbol m1Owner = (TypeSymbol)m1.owner;
TypeSymbol m2Owner = (TypeSymbol)m2.owner; TypeSymbol m2Owner = (TypeSymbol)m2.owner;
...@@ -738,24 +739,24 @@ public class Resolve { ...@@ -738,24 +739,24 @@ public class Resolve {
if (m2Abstract && !m1Abstract) return m1; if (m2Abstract && !m1Abstract) return m1;
// both abstract or both concrete // both abstract or both concrete
if (!m1Abstract && !m2Abstract) if (!m1Abstract && !m2Abstract)
return new AmbiguityError(m1, m2); return ambiguityError(m1, m2);
// check that both signatures have the same erasure // check that both signatures have the same erasure
if (!types.isSameTypes(m1.erasure(types).getParameterTypes(), if (!types.isSameTypes(m1.erasure(types).getParameterTypes(),
m2.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 // both abstract, neither overridden; merge throws clause and result type
Symbol mostSpecific; Symbol mostSpecific;
Type result2 = mt2.getReturnType(); Type result2 = mt2.getReturnType();
if (mt2.tag == FORALL) if (mt2.tag == FORALL)
result2 = types.subst(result2, ((ForAll)mt2).tvars, ((ForAll)mt1).tvars); result2 = types.subst(result2, ((ForAll)mt2).tvars, ((ForAll)mt1).tvars);
if (types.isSubtype(mt1.getReturnType(), result2)) { if (types.isSubtype(mt1.getReturnType(), result2))
mostSpecific = m1; mostSpecific = m1;
} else if (types.isSubtype(result2, mt1.getReturnType())) { else if (types.isSubtype(result2, mt1.getReturnType()))
mostSpecific = m2; mostSpecific = m2;
} else { else {
// Theoretically, this can't happen, but it is possible // Theoretically, this can't happen, but it is possible
// due to error recovery or mixing incompatible class files // due to error recovery or mixing incompatible class files
return new AmbiguityError(m1, m2); return ambiguityError(m1, m2);
} }
MethodSymbol result = new MethodSymbol( MethodSymbol result = new MethodSymbol(
mostSpecific.flags(), mostSpecific.flags(),
...@@ -777,7 +778,7 @@ public class Resolve { ...@@ -777,7 +778,7 @@ public class Resolve {
} }
if (m1SignatureMoreSpecific) return m1; if (m1SignatureMoreSpecific) return m1;
if (m2SignatureMoreSpecific) return m2; if (m2SignatureMoreSpecific) return m2;
return new AmbiguityError(m1, m2); return ambiguityError(m1, m2);
case AMBIGUOUS: case AMBIGUOUS:
AmbiguityError e = (AmbiguityError)m2; AmbiguityError e = (AmbiguityError)m2;
Symbol err1 = mostSpecific(m1, e.sym, env, site, allowBoxing, useVarargs); Symbol err1 = mostSpecific(m1, e.sym, env, site, allowBoxing, useVarargs);
...@@ -787,9 +788,9 @@ public class Resolve { ...@@ -787,9 +788,9 @@ public class Resolve {
if (err1 instanceof AmbiguityError && if (err1 instanceof AmbiguityError &&
err2 instanceof AmbiguityError && err2 instanceof AmbiguityError &&
((AmbiguityError)err1).sym == ((AmbiguityError)err2).sym) ((AmbiguityError)err1).sym == ((AmbiguityError)err2).sym)
return new AmbiguityError(m1, m2); return ambiguityError(m1, m2);
else else
return new AmbiguityError(err1, err2); return ambiguityError(err1, err2);
default: default:
throw new AssertionError(); throw new AssertionError();
} }
...@@ -844,6 +845,14 @@ public class Resolve { ...@@ -844,6 +845,14 @@ public class Resolve {
return to; 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 /** Find best qualified method matching given name, type and value
* arguments. * arguments.
......
/*
* @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<String> ls) {}
void m(List<Integer> li) {}
{ m(Arrays.asList(12)); }
}
T6910550a.java:13:10: compiler.err.name.clash.same.erasure: m(java.util.List<java.lang.Integer>), m(java.util.List<java.lang.String>)
1 error
/*
* @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<X, Y, Z> {
void m(X x) {}
void m(Y y) {}
void m(Z y) {}
{ m(null); }
}
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
/*
* @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); }
}
T6910550c.java:12:10: compiler.err.array.and.varargs: m(java.lang.Object...), m(java.lang.Object[]), T6910550c
1 error
/*
* @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 {
<X> void m(X x) {}
<Y> void m(Y y) {}
{ m(null); }
}
T6910550d.java:12:14: compiler.err.already.defined: <X>m(X), T6910550d
1 error
/*
* @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<X,Y> {}
<X> void m(Pair<X,X> x) {}
<X,Y> void m(Pair<X,Y> y) {}
{ m(new Pair<String,String>());
m(new Pair<String,Integer>()); }
}
T6910550e.java:14:16: compiler.err.name.clash.same.erasure: <X,Y>m(T6910550e.Pair<X,Y>), <X>m(T6910550e.Pair<X,X>)
1 error
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册