Mon, 06 Dec 2010 11:51:02 +0000
5088429: varargs overloading problem
Summary: compiler implementation for overload resolution w/ varargs method does not match JLS
Reviewed-by: jjg
1.1 --- a/src/share/classes/com/sun/tools/javac/comp/Resolve.java Mon Dec 06 11:50:37 2010 +0000 1.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Resolve.java Mon Dec 06 11:51:02 2010 +0000 1.3 @@ -724,23 +724,11 @@ 1.4 switch (m2.kind) { 1.5 case MTH: 1.6 if (m1 == m2) return m1; 1.7 - Type mt1 = types.memberType(site, m1); 1.8 - noteWarner.unchecked = false; 1.9 - boolean m1SignatureMoreSpecific = 1.10 - (instantiate(env, site, m2, types.lowerBoundArgtypes(mt1), null, 1.11 - allowBoxing, false, noteWarner) != null || 1.12 - useVarargs && instantiate(env, site, m2, types.lowerBoundArgtypes(mt1), null, 1.13 - allowBoxing, true, noteWarner) != null) && 1.14 - !noteWarner.unchecked; 1.15 - Type mt2 = types.memberType(site, m2); 1.16 - noteWarner.unchecked = false; 1.17 - boolean m2SignatureMoreSpecific = 1.18 - (instantiate(env, site, m1, types.lowerBoundArgtypes(mt2), null, 1.19 - allowBoxing, false, noteWarner) != null || 1.20 - useVarargs && instantiate(env, site, m1, types.lowerBoundArgtypes(mt2), null, 1.21 - allowBoxing, true, noteWarner) != null) && 1.22 - !noteWarner.unchecked; 1.23 + boolean m1SignatureMoreSpecific = signatureMoreSpecific(env, site, m1, m2, allowBoxing, useVarargs); 1.24 + boolean m2SignatureMoreSpecific = signatureMoreSpecific(env, site, m2, m1, allowBoxing, useVarargs); 1.25 if (m1SignatureMoreSpecific && m2SignatureMoreSpecific) { 1.26 + Type mt1 = types.memberType(site, m1); 1.27 + Type mt2 = types.memberType(site, m2); 1.28 if (!types.overrideEquivalent(mt1, mt2)) 1.29 return new AmbiguityError(m1, m2); 1.30 // same signature; select (a) the non-bridge method, or 1.31 @@ -824,6 +812,50 @@ 1.32 throw new AssertionError(); 1.33 } 1.34 } 1.35 + //where 1.36 + private boolean signatureMoreSpecific(Env<AttrContext> env, Type site, Symbol m1, Symbol m2, boolean allowBoxing, boolean useVarargs) { 1.37 + Type mtype1 = types.memberType(site, adjustVarargs(m1, m2, useVarargs)); 1.38 + noteWarner.unchecked = false; 1.39 + return (instantiate(env, site, adjustVarargs(m2, m1, useVarargs), types.lowerBoundArgtypes(mtype1), null, 1.40 + allowBoxing, false, noteWarner) != null || 1.41 + useVarargs && instantiate(env, site, adjustVarargs(m2, m1, useVarargs), types.lowerBoundArgtypes(mtype1), null, 1.42 + allowBoxing, true, noteWarner) != null) && 1.43 + !noteWarner.unchecked; 1.44 + } 1.45 + //where 1.46 + private Symbol adjustVarargs(Symbol to, Symbol from, boolean useVarargs) { 1.47 + List<Type> fromArgs = from.type.getParameterTypes(); 1.48 + List<Type> toArgs = to.type.getParameterTypes(); 1.49 + if (useVarargs && 1.50 + toArgs.length() < fromArgs.length() && 1.51 + (from.flags() & VARARGS) != 0 && 1.52 + (to.flags() & VARARGS) != 0) { 1.53 + //if we are checking a varargs method 'from' against another varargs 1.54 + //method 'to' (where arity of 'to' < arity of 'from') then expand signature 1.55 + //of 'to' to 'fit' arity of 'from' (this means adding fake formals to 'to' 1.56 + //until 'to' signature has the same arity as 'from') 1.57 + ListBuffer<Type> args = ListBuffer.lb(); 1.58 + Type varargsTypeFrom = fromArgs.last(); 1.59 + Type varargsTypeTo = toArgs.last(); 1.60 + while (fromArgs.head != varargsTypeFrom) { 1.61 + args.append(toArgs.head == varargsTypeTo ? types.elemtype(varargsTypeTo) : toArgs.head); 1.62 + fromArgs = fromArgs.tail; 1.63 + toArgs = toArgs.head == varargsTypeTo ? 1.64 + toArgs : 1.65 + toArgs.tail; 1.66 + } 1.67 + args.append(varargsTypeTo); 1.68 + MethodSymbol msym = new MethodSymbol(to.flags_field, 1.69 + to.name, 1.70 + (Type)to.type.clone(), //see: 6990136 1.71 + to.owner); 1.72 + MethodType mtype = msym.type.asMethodType(); 1.73 + mtype.argtypes = args.toList(); 1.74 + return msym; 1.75 + } else { 1.76 + return to; 1.77 + } 1.78 + } 1.79 1.80 /** Find best qualified method matching given name, type and value 1.81 * arguments.
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/test/tools/javac/varargs/5088429/T5088429Neg01.java Mon Dec 06 11:51:02 2010 +0000 2.3 @@ -0,0 +1,44 @@ 2.4 +/* 2.5 + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. 2.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 2.7 + * 2.8 + * This code is free software; you can redistribute it and/or modify it 2.9 + * under the terms of the GNU General Public License version 2 only, as 2.10 + * published by the Free Software Foundation. 2.11 + * 2.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 2.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 2.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 2.15 + * version 2 for more details (a copy is included in the LICENSE file that 2.16 + * accompanied this code). 2.17 + * 2.18 + * You should have received a copy of the GNU General Public License version 2.19 + * 2 along with this work; if not, write to the Free Software Foundation, 2.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2.21 + * 2.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2.23 + * or visit www.oracle.com if you need additional information or have any 2.24 + * questions. 2.25 + */ 2.26 + 2.27 +/* 2.28 + * @test 2.29 + * @bug 5088429 2.30 + * 2.31 + * @summary varargs overloading problem 2.32 + * @author mcimadamore 2.33 + * @compile/fail/ref=T5088429Neg01.out -XDrawDiagnostics T5088429Neg01.java 2.34 + * 2.35 + */ 2.36 + 2.37 +class T5088429Neg01 { 2.38 + interface A {} 2.39 + interface B extends A {} 2.40 + 2.41 + T5088429Neg01(A... args) {} 2.42 + T5088429Neg01(A a, A... args) {} 2.43 + 2.44 + void test(B b) { 2.45 + new T5088429Neg01(b); 2.46 + } 2.47 +}
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 3.2 +++ b/test/tools/javac/varargs/5088429/T5088429Neg01.out Mon Dec 06 11:51:02 2010 +0000 3.3 @@ -0,0 +1,2 @@ 3.4 +T5088429Neg01.java:42:9: compiler.err.ref.ambiguous: T5088429Neg01, kindname.constructor, T5088429Neg01(T5088429Neg01.A...), T5088429Neg01, kindname.constructor, T5088429Neg01(T5088429Neg01.A,T5088429Neg01.A...), T5088429Neg01 3.5 +1 error
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 4.2 +++ b/test/tools/javac/varargs/5088429/T5088429Neg02.java Mon Dec 06 11:51:02 2010 +0000 4.3 @@ -0,0 +1,44 @@ 4.4 +/* 4.5 + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. 4.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4.7 + * 4.8 + * This code is free software; you can redistribute it and/or modify it 4.9 + * under the terms of the GNU General Public License version 2 only, as 4.10 + * published by the Free Software Foundation. 4.11 + * 4.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 4.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 4.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 4.15 + * version 2 for more details (a copy is included in the LICENSE file that 4.16 + * accompanied this code). 4.17 + * 4.18 + * You should have received a copy of the GNU General Public License version 4.19 + * 2 along with this work; if not, write to the Free Software Foundation, 4.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 4.21 + * 4.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 4.23 + * or visit www.oracle.com if you need additional information or have any 4.24 + * questions. 4.25 + */ 4.26 + 4.27 +/* 4.28 + * @test 4.29 + * @bug 5088429 4.30 + * 4.31 + * @summary varargs overloading problem 4.32 + * @author mcimadamore 4.33 + * @compile/fail/ref=T5088429Neg02.out -XDrawDiagnostics T5088429Neg02.java 4.34 + * 4.35 + */ 4.36 + 4.37 +class T5088429Neg02 { 4.38 + interface A {} 4.39 + interface B extends A {} 4.40 + 4.41 + void m(A... args) {} 4.42 + void m(A a, A... args) {} 4.43 + 4.44 + void test(B b) { 4.45 + m(b); 4.46 + } 4.47 +}
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 5.2 +++ b/test/tools/javac/varargs/5088429/T5088429Neg02.out Mon Dec 06 11:51:02 2010 +0000 5.3 @@ -0,0 +1,2 @@ 5.4 +T5088429Neg02.java:42:9: compiler.err.ref.ambiguous: m, kindname.method, m(T5088429Neg02.A...), T5088429Neg02, kindname.method, m(T5088429Neg02.A,T5088429Neg02.A...), T5088429Neg02 5.5 +1 error
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 6.2 +++ b/test/tools/javac/varargs/5088429/T5088429Pos01.java Mon Dec 06 11:51:02 2010 +0000 6.3 @@ -0,0 +1,44 @@ 6.4 +/* 6.5 + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. 6.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 6.7 + * 6.8 + * This code is free software; you can redistribute it and/or modify it 6.9 + * under the terms of the GNU General Public License version 2 only, as 6.10 + * published by the Free Software Foundation. 6.11 + * 6.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 6.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 6.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 6.15 + * version 2 for more details (a copy is included in the LICENSE file that 6.16 + * accompanied this code). 6.17 + * 6.18 + * You should have received a copy of the GNU General Public License version 6.19 + * 2 along with this work; if not, write to the Free Software Foundation, 6.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 6.21 + * 6.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 6.23 + * or visit www.oracle.com if you need additional information or have any 6.24 + * questions. 6.25 + */ 6.26 + 6.27 +/* 6.28 + * @test 6.29 + * @bug 5088429 6.30 + * 6.31 + * @summary varargs overloading problem 6.32 + * @author mcimadamore 6.33 + * @compile T5088429Pos01.java 6.34 + * 6.35 + */ 6.36 + 6.37 +class T5088429Pos01 { 6.38 + interface A {} 6.39 + interface B extends A {} 6.40 + 6.41 + T5088429Pos01(A... args) {} 6.42 + T5088429Pos01(B b, A... args) {} 6.43 + 6.44 + void test(B b) { 6.45 + new T5088429Pos01(b); 6.46 + } 6.47 +}
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 7.2 +++ b/test/tools/javac/varargs/5088429/T5088429Pos02.java Mon Dec 06 11:51:02 2010 +0000 7.3 @@ -0,0 +1,44 @@ 7.4 +/* 7.5 + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. 7.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 7.7 + * 7.8 + * This code is free software; you can redistribute it and/or modify it 7.9 + * under the terms of the GNU General Public License version 2 only, as 7.10 + * published by the Free Software Foundation. 7.11 + * 7.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 7.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 7.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 7.15 + * version 2 for more details (a copy is included in the LICENSE file that 7.16 + * accompanied this code). 7.17 + * 7.18 + * You should have received a copy of the GNU General Public License version 7.19 + * 2 along with this work; if not, write to the Free Software Foundation, 7.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 7.21 + * 7.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 7.23 + * or visit www.oracle.com if you need additional information or have any 7.24 + * questions. 7.25 + */ 7.26 + 7.27 +/* 7.28 + * @test 7.29 + * @bug 5088429 7.30 + * 7.31 + * @summary varargs overloading problem 7.32 + * @author mcimadamore 7.33 + * @compile T5088429Pos02.java 7.34 + * 7.35 + */ 7.36 + 7.37 +class T5088429Pos02 { 7.38 + interface A {} 7.39 + interface B extends A {} 7.40 + 7.41 + void m(A... args) {} 7.42 + void m(B b, A... args) {} 7.43 + 7.44 + void test(B b) { 7.45 + m(b); 7.46 + } 7.47 +}