# HG changeset patch # User mcimadamore # Date 1233231477 0 # Node ID 1aa81917016abdf943f814d0205cdda4cff0beb6 # Parent 9199b9092f73769b17582a5568ceb77b41ed7bf5 6315770: javac inference allows creation of strange types: Integer & Runnable Summary: Javac does not apply glb correctly as per JLS3 15.12.2.8 Reviewed-by: jjg diff -r 9199b9092f73 -r 1aa81917016a src/share/classes/com/sun/tools/javac/code/Types.java --- a/src/share/classes/com/sun/tools/javac/code/Types.java Tue Jan 27 18:38:39 2009 -0800 +++ b/src/share/classes/com/sun/tools/javac/code/Types.java Thu Jan 29 12:17:57 2009 +0000 @@ -709,12 +709,31 @@ case UNDETVAR: if (s.tag == WILDCARD) { UndetVar undetvar = (UndetVar)t; - undetvar.inst = glb(upperBound(s), undetvar.inst); - // We should check instantiated type against any of the - // undetvar's lower bounds. - for (Type t2 : undetvar.lobounds) { - if (!isSubtype(t2, undetvar.inst)) - return false; + WildcardType wt = (WildcardType)s; + switch(wt.kind) { + case UNBOUND: //similar to ? extends Object + case EXTENDS: { + Type bound = upperBound(s); + // We should check the new upper bound against any of the + // undetvar's lower bounds. + for (Type t2 : undetvar.lobounds) { + if (!isSubtype(t2, bound)) + return false; + } + undetvar.hibounds = undetvar.hibounds.prepend(bound); + break; + } + case SUPER: { + Type bound = lowerBound(s); + // We should check the new lower bound against any of the + // undetvar's lower bounds. + for (Type t2 : undetvar.hibounds) { + if (!isSubtype(bound, t2)) + return false; + } + undetvar.lobounds = undetvar.lobounds.prepend(bound); + break; + } } return true; } else { @@ -2825,6 +2844,16 @@ // // + public Type glb(List ts) { + Type t1 = ts.head; + for (Type t2 : ts.tail) { + if (t1.isErroneous()) + return t1; + t1 = glb(t1, t2); + } + return t1; + } + //where public Type glb(Type t, Type s) { if (s == null) return t; diff -r 9199b9092f73 -r 1aa81917016a src/share/classes/com/sun/tools/javac/comp/Infer.java --- a/src/share/classes/com/sun/tools/javac/comp/Infer.java Tue Jan 27 18:38:39 2009 -0800 +++ b/src/share/classes/com/sun/tools/javac/comp/Infer.java Thu Jan 29 12:17:57 2009 +0000 @@ -154,33 +154,15 @@ that.inst = syms.objectType; else if (that.hibounds.tail.isEmpty()) that.inst = that.hibounds.head; - else { - for (List bs = that.hibounds; - bs.nonEmpty() && that.inst == null; - bs = bs.tail) { - // System.out.println("hibounds = " + that.hibounds);//DEBUG - if (isSubClass(bs.head, that.hibounds)) - that.inst = types.fromUnknownFun.apply(bs.head); - } - if (that.inst == null) { - int classCount = 0, interfaceCount = 0; - for (Type t : that.hibounds) { - if (t.tag == CLASS) { - if (t.isInterface()) - interfaceCount++; - else - classCount++; - } - } - if ((that.hibounds.size() == classCount + interfaceCount) && classCount == 1) - that.inst = types.makeCompoundType(that.hibounds); - } - if (that.inst == null || !types.isSubtypeUnchecked(that.inst, that.hibounds, warn)) - throw ambiguousNoInstanceException - .setMessage("no.unique.maximal.instance.exists", - that.qtype, that.hibounds); - } + else + that.inst = types.glb(that.hibounds); } + if (that.inst == null || + that.inst.isErroneous() || + !types.isSubtypeUnchecked(that.inst, that.hibounds, warn)) + throw ambiguousNoInstanceException + .setMessage("no.unique.maximal.instance.exists", + that.qtype, that.hibounds); } //where private boolean isSubClass(Type t, final List ts) { diff -r 9199b9092f73 -r 1aa81917016a test/tools/javac/generics/inference/6315770/T6315770.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/generics/inference/6315770/T6315770.java Thu Jan 29 12:17:57 2009 +0000 @@ -0,0 +1,42 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/** + * @test + * @bug 6315770 + * @summary javac inference allows creation of strange types: Integer & Runnable + * @author Maurizio Cimadamore + * + * @compile/fail/ref=T6315770.out T6315770.java -XDrawDiagnostics + */ + +class T6315770 { + T6315770 m() { + return null; + } + void test() { + T6315770 c1 = m(); + T6315770 c2 = m(); + T6315770 c3 = m(); + } +} diff -r 9199b9092f73 -r 1aa81917016a test/tools/javac/generics/inference/6315770/T6315770.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/generics/inference/6315770/T6315770.out Thu Jan 29 12:17:57 2009 +0000 @@ -0,0 +1,3 @@ +T6315770.java:39:42: compiler.err.undetermined.type.1: T6315770, (- compiler.misc.no.unique.maximal.instance.exists: T, java.lang.String,java.lang.Integer,java.lang.Runnable) +T6315770.java:40:40: compiler.err.prob.found.req: (- compiler.misc.incompatible.types.1: (- compiler.misc.no.conforming.instance.exists: T, T6315770, T6315770)), T6315770, T6315770 +2 errors