# HG changeset patch # User vromero # Date 1381867341 -3600 # Node ID 9d4e765fe447077aa01966e0d12e703936337a77 # Parent e1efbecefefa99a618ccc4df276ed1ae18317332 8024947: javac should issue the potentially ambiguous overload warning only where the problem appears Reviewed-by: jjg diff -r e1efbecefefa -r 9d4e765fe447 langtools/src/share/classes/com/sun/tools/javac/comp/Check.java --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java Tue Oct 15 19:36:45 2013 +0100 +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java Tue Oct 15 21:02:21 2013 +0100 @@ -2399,13 +2399,28 @@ ClashFilter cf = new ClashFilter(site); //for each method m1 that is overridden (directly or indirectly) //by method 'sym' in 'site'... + + List potentiallyAmbiguousList = List.nil(); + boolean overridesAny = false; for (Symbol m1 : types.membersClosure(site, false).getElementsByName(sym.name, cf)) { - if (!sym.overrides(m1, site.tsym, types, false)) { - checkPotentiallyAmbiguousOverloads(pos, site, sym, (MethodSymbol)m1); - continue; - } - //...check each method m2 that is a member of 'site' - for (Symbol m2 : types.membersClosure(site, false).getElementsByName(sym.name, cf)) { + if (!sym.overrides(m1, site.tsym, types, false)) { + if (m1 == sym) { + continue; + } + + if (!overridesAny) { + potentiallyAmbiguousList = potentiallyAmbiguousList.prepend((MethodSymbol)m1); + } + continue; + } + + if (m1 != sym) { + overridesAny = true; + potentiallyAmbiguousList = List.nil(); + } + + //...check each method m2 that is a member of 'site' + for (Symbol m2 : types.membersClosure(site, false).getElementsByName(sym.name, cf)) { if (m2 == m1) continue; //if (i) the signature of 'sym' is not a subsignature of m1 (seen as //a member of 'site') and (ii) m1 has the same erasure as m2, issue an error @@ -2424,10 +2439,14 @@ } } } + + if (!overridesAny) { + for (MethodSymbol m: potentiallyAmbiguousList) { + checkPotentiallyAmbiguousOverloads(pos, site, sym, m); + } + } } - - /** Check that all static methods accessible from 'site' are * mutually compatible (JLS 8.4.8). * diff -r e1efbecefefa -r 9d4e765fe447 langtools/test/tools/javac/lambda/T8024947/PotentiallyAmbiguousWarningTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/lambda/T8024947/PotentiallyAmbiguousWarningTest.java Tue Oct 15 21:02:21 2013 +0100 @@ -0,0 +1,97 @@ +/* + * 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 + * @bug 8024947 + * @summary javac should issue the potentially ambiguous overload warning only + * where the problem appears + * @compile/fail/ref=PotentiallyAmbiguousWarningTest.out -XDrawDiagnostics -Werror -Xlint:overloads PotentiallyAmbiguousWarningTest.java + * @compile PotentiallyAmbiguousWarningTest.java + */ + +import java.util.function.*; + +public interface PotentiallyAmbiguousWarningTest { + + //a warning should be fired + interface I1 { + void foo(Consumer c); + void foo(IntConsumer c); + } + + //a warning should be fired + class C1 { + void foo(Consumer c) { } + void foo(IntConsumer c) { } + } + + interface I2 { + void foo(Consumer c); + } + + //a warning should be fired, J1 is provoking the issue + interface J1 extends I2 { + void foo(IntConsumer c); + } + + //no warning here, the issue is introduced in I1 + interface I3 extends I1 {} + + //no warning here, the issue is introduced in I1. I4 is just overriding an existing method + interface I4 extends I1 { + void foo(IntConsumer c); + } + + class C2 { + void foo(Consumer c) { } + } + + //a warning should be fired, D1 is provoking the issue + class D1 extends C2 { + void foo(IntConsumer c) { } + } + + //a warning should be fired, C3 is provoking the issue + class C3 implements I2 { + public void foo(Consumer c) { } + public void foo(IntConsumer c) { } + } + + //no warning here, the issue is introduced in C1 + class C4 extends C1 {} + + //no warning here, the issue is introduced in C1. C5 is just overriding an existing method + class C5 extends C1 { + void foo(IntConsumer c) {} + } + + interface I5 { + void foo(T c); + } + + //a warning should be fired, J2 is provoking the issue + interface J2 extends I5 { + void foo(Consumer c); + } +} diff -r e1efbecefefa -r 9d4e765fe447 langtools/test/tools/javac/lambda/T8024947/PotentiallyAmbiguousWarningTest.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/lambda/T8024947/PotentiallyAmbiguousWarningTest.out Tue Oct 15 21:02:21 2013 +0100 @@ -0,0 +1,9 @@ +PotentiallyAmbiguousWarningTest.java:39:14: compiler.warn.potentially.ambiguous.overload: foo(java.util.function.Consumer), PotentiallyAmbiguousWarningTest.I1, foo(java.util.function.IntConsumer), PotentiallyAmbiguousWarningTest.I1 +PotentiallyAmbiguousWarningTest.java:45:14: compiler.warn.potentially.ambiguous.overload: foo(java.util.function.Consumer), PotentiallyAmbiguousWarningTest.C1, foo(java.util.function.IntConsumer), PotentiallyAmbiguousWarningTest.C1 +PotentiallyAmbiguousWarningTest.java:55:14: compiler.warn.potentially.ambiguous.overload: foo(java.util.function.IntConsumer), PotentiallyAmbiguousWarningTest.J1, foo(java.util.function.Consumer), PotentiallyAmbiguousWarningTest.I2 +PotentiallyAmbiguousWarningTest.java:72:14: compiler.warn.potentially.ambiguous.overload: foo(java.util.function.IntConsumer), PotentiallyAmbiguousWarningTest.D1, foo(java.util.function.Consumer), PotentiallyAmbiguousWarningTest.C2 +PotentiallyAmbiguousWarningTest.java:78:21: compiler.warn.potentially.ambiguous.overload: foo(java.util.function.IntConsumer), PotentiallyAmbiguousWarningTest.C3, foo(java.util.function.Consumer), PotentiallyAmbiguousWarningTest.C3 +PotentiallyAmbiguousWarningTest.java:95:14: compiler.warn.potentially.ambiguous.overload: foo(java.util.function.Consumer), PotentiallyAmbiguousWarningTest.J2, foo(T), PotentiallyAmbiguousWarningTest.I5 +- compiler.err.warnings.and.werror +1 error +6 warnings