diff --git a/src/share/classes/com/sun/tools/javac/comp/Resolve.java b/src/share/classes/com/sun/tools/javac/comp/Resolve.java index c8b83de45355d4a9341a8e3db85fd673d1bfaabe..758c430f46c6da9c5cc18a1fb31237f96594fffa 100644 --- a/src/share/classes/com/sun/tools/javac/comp/Resolve.java +++ b/src/share/classes/com/sun/tools/javac/comp/Resolve.java @@ -724,23 +724,11 @@ public class Resolve { switch (m2.kind) { case MTH: if (m1 == m2) return m1; - Type mt1 = types.memberType(site, m1); - noteWarner.unchecked = false; - boolean m1SignatureMoreSpecific = - (instantiate(env, site, m2, types.lowerBoundArgtypes(mt1), null, - allowBoxing, false, noteWarner) != null || - useVarargs && instantiate(env, site, m2, types.lowerBoundArgtypes(mt1), null, - allowBoxing, true, noteWarner) != null) && - !noteWarner.unchecked; - Type mt2 = types.memberType(site, m2); - noteWarner.unchecked = false; - boolean m2SignatureMoreSpecific = - (instantiate(env, site, m1, types.lowerBoundArgtypes(mt2), null, - allowBoxing, false, noteWarner) != null || - useVarargs && instantiate(env, site, m1, types.lowerBoundArgtypes(mt2), null, - allowBoxing, true, noteWarner) != null) && - !noteWarner.unchecked; + boolean m1SignatureMoreSpecific = signatureMoreSpecific(env, site, m1, m2, allowBoxing, useVarargs); + boolean m2SignatureMoreSpecific = signatureMoreSpecific(env, site, m2, m1, allowBoxing, useVarargs); if (m1SignatureMoreSpecific && m2SignatureMoreSpecific) { + Type mt1 = types.memberType(site, m1); + Type mt2 = types.memberType(site, m2); if (!types.overrideEquivalent(mt1, mt2)) return new AmbiguityError(m1, m2); // same signature; select (a) the non-bridge method, or @@ -824,6 +812,50 @@ public class Resolve { throw new AssertionError(); } } + //where + private boolean signatureMoreSpecific(Env env, Type site, Symbol m1, Symbol m2, boolean allowBoxing, boolean useVarargs) { + Type mtype1 = types.memberType(site, adjustVarargs(m1, m2, useVarargs)); + noteWarner.unchecked = false; + return (instantiate(env, site, adjustVarargs(m2, m1, useVarargs), types.lowerBoundArgtypes(mtype1), null, + allowBoxing, false, noteWarner) != null || + useVarargs && instantiate(env, site, adjustVarargs(m2, m1, useVarargs), types.lowerBoundArgtypes(mtype1), null, + allowBoxing, true, noteWarner) != null) && + !noteWarner.unchecked; + } + //where + private Symbol adjustVarargs(Symbol to, Symbol from, boolean useVarargs) { + List fromArgs = from.type.getParameterTypes(); + List toArgs = to.type.getParameterTypes(); + if (useVarargs && + toArgs.length() < fromArgs.length() && + (from.flags() & VARARGS) != 0 && + (to.flags() & VARARGS) != 0) { + //if we are checking a varargs method 'from' against another varargs + //method 'to' (where arity of 'to' < arity of 'from') then expand signature + //of 'to' to 'fit' arity of 'from' (this means adding fake formals to 'to' + //until 'to' signature has the same arity as 'from') + ListBuffer args = ListBuffer.lb(); + Type varargsTypeFrom = fromArgs.last(); + Type varargsTypeTo = toArgs.last(); + while (fromArgs.head != varargsTypeFrom) { + args.append(toArgs.head == varargsTypeTo ? types.elemtype(varargsTypeTo) : toArgs.head); + fromArgs = fromArgs.tail; + toArgs = toArgs.head == varargsTypeTo ? + toArgs : + toArgs.tail; + } + args.append(varargsTypeTo); + MethodSymbol msym = new MethodSymbol(to.flags_field, + to.name, + (Type)to.type.clone(), //see: 6990136 + to.owner); + MethodType mtype = msym.type.asMethodType(); + mtype.argtypes = args.toList(); + return msym; + } else { + return to; + } + } /** Find best qualified method matching given name, type and value * arguments. diff --git a/test/tools/javac/varargs/5088429/T5088429Neg01.java b/test/tools/javac/varargs/5088429/T5088429Neg01.java new file mode 100644 index 0000000000000000000000000000000000000000..723bac09f5e5a1add58b431eb192e5994213fe6c --- /dev/null +++ b/test/tools/javac/varargs/5088429/T5088429Neg01.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2010, 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 5088429 + * + * @summary varargs overloading problem + * @author mcimadamore + * @compile/fail/ref=T5088429Neg01.out -XDrawDiagnostics T5088429Neg01.java + * + */ + +class T5088429Neg01 { + interface A {} + interface B extends A {} + + T5088429Neg01(A... args) {} + T5088429Neg01(A a, A... args) {} + + void test(B b) { + new T5088429Neg01(b); + } +} diff --git a/test/tools/javac/varargs/5088429/T5088429Neg01.out b/test/tools/javac/varargs/5088429/T5088429Neg01.out new file mode 100644 index 0000000000000000000000000000000000000000..4661eb001295d80b7b4cbd90280243b27688afe5 --- /dev/null +++ b/test/tools/javac/varargs/5088429/T5088429Neg01.out @@ -0,0 +1,2 @@ +T5088429Neg01.java:42:9: compiler.err.ref.ambiguous: T5088429Neg01, kindname.constructor, T5088429Neg01(T5088429Neg01.A...), T5088429Neg01, kindname.constructor, T5088429Neg01(T5088429Neg01.A,T5088429Neg01.A...), T5088429Neg01 +1 error diff --git a/test/tools/javac/varargs/5088429/T5088429Neg02.java b/test/tools/javac/varargs/5088429/T5088429Neg02.java new file mode 100644 index 0000000000000000000000000000000000000000..ede3aa72353f7b54eb8eac65845c36d88e00f091 --- /dev/null +++ b/test/tools/javac/varargs/5088429/T5088429Neg02.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2010, 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 5088429 + * + * @summary varargs overloading problem + * @author mcimadamore + * @compile/fail/ref=T5088429Neg02.out -XDrawDiagnostics T5088429Neg02.java + * + */ + +class T5088429Neg02 { + interface A {} + interface B extends A {} + + void m(A... args) {} + void m(A a, A... args) {} + + void test(B b) { + m(b); + } +} diff --git a/test/tools/javac/varargs/5088429/T5088429Neg02.out b/test/tools/javac/varargs/5088429/T5088429Neg02.out new file mode 100644 index 0000000000000000000000000000000000000000..279c0f29b7995d42a3c52596fc26ca89d296a667 --- /dev/null +++ b/test/tools/javac/varargs/5088429/T5088429Neg02.out @@ -0,0 +1,2 @@ +T5088429Neg02.java:42:9: compiler.err.ref.ambiguous: m, kindname.method, m(T5088429Neg02.A...), T5088429Neg02, kindname.method, m(T5088429Neg02.A,T5088429Neg02.A...), T5088429Neg02 +1 error diff --git a/test/tools/javac/varargs/5088429/T5088429Pos01.java b/test/tools/javac/varargs/5088429/T5088429Pos01.java new file mode 100644 index 0000000000000000000000000000000000000000..ad2e2fcbb474f53806fd13115406a42320fac7f9 --- /dev/null +++ b/test/tools/javac/varargs/5088429/T5088429Pos01.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2010, 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 5088429 + * + * @summary varargs overloading problem + * @author mcimadamore + * @compile T5088429Pos01.java + * + */ + +class T5088429Pos01 { + interface A {} + interface B extends A {} + + T5088429Pos01(A... args) {} + T5088429Pos01(B b, A... args) {} + + void test(B b) { + new T5088429Pos01(b); + } +} diff --git a/test/tools/javac/varargs/5088429/T5088429Pos02.java b/test/tools/javac/varargs/5088429/T5088429Pos02.java new file mode 100644 index 0000000000000000000000000000000000000000..abf0ec707834190939125748105b7cd8ea3431d7 --- /dev/null +++ b/test/tools/javac/varargs/5088429/T5088429Pos02.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2010, 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 5088429 + * + * @summary varargs overloading problem + * @author mcimadamore + * @compile T5088429Pos02.java + * + */ + +class T5088429Pos02 { + interface A {} + interface B extends A {} + + void m(A... args) {} + void m(B b, A... args) {} + + void test(B b) { + m(b); + } +}