# HG changeset patch # User lana # Date 1426806820 25200 # Node ID 17efac395638494091b058b6a5075cedb73984c1 # Parent 4bfc61b8c9b097717f3c01ef7c7970d17f196739# Parent f539d3fc9d72a75c41856dd333e0b1be37fd57ea Merge diff -r 4bfc61b8c9b0 -r 17efac395638 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Type.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Type.java Thu Mar 19 12:59:26 2015 -0700 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Type.java Thu Mar 19 16:13:40 2015 -0700 @@ -31,10 +31,12 @@ import java.util.EnumSet; import java.util.Map; import java.util.Set; +import java.util.function.Function; import javax.lang.model.type.*; import com.sun.tools.javac.code.Symbol.*; +import com.sun.tools.javac.code.Types.MapVisitor; import com.sun.tools.javac.util.*; import com.sun.tools.javac.util.DefinedBy.Api; import static com.sun.tools.javac.code.BoundKind.*; @@ -218,33 +220,81 @@ /** An abstract class for mappings from types to types */ - public static abstract class Mapping { - private String name; - public Mapping(String name) { - this.name = name; + public static abstract class TypeMapping extends Types.MapVisitor implements Function { + + @Override + public Type apply(Type type) { + return visit(type); + } + + List visit(List ts, S s) { + return ts.map(t -> visit(t, s)); + } + + @Override + public Type visitClassType(ClassType t, S s) { + Type outer = t.getEnclosingType(); + Type outer1 = visit(outer, s); + List typarams = t.getTypeArguments(); + List typarams1 = visit(typarams, s); + if (outer1 == outer && typarams1 == typarams) return t; + else return new ClassType(outer1, typarams1, t.tsym, t.metadata); + } + + @Override + public Type visitWildcardType(WildcardType wt, S s) { + Type t = wt.type; + if (t != null) + t = visit(t, s); + if (t == wt.type) + return wt; + else + return new WildcardType(t, wt.kind, wt.tsym, wt.bound, wt.metadata); } - public abstract Type apply(Type t); - public String toString() { - return name; + + @Override + public Type visitArrayType(ArrayType t, S s) { + Type elemtype = t.elemtype; + Type elemtype1 = visit(elemtype, s); + if (elemtype1 == elemtype) return t; + else return new ArrayType(elemtype1, t.tsym, t.metadata); + } + + @Override + public Type visitMethodType(MethodType t, S s) { + List argtypes = t.argtypes; + Type restype = t.restype; + List thrown = t.thrown; + List argtypes1 = visit(argtypes, s); + Type restype1 = visit(restype, s); + List thrown1 = visit(thrown, s); + if (argtypes1 == argtypes && + restype1 == restype && + thrown1 == thrown) return t; + else return new MethodType(argtypes1, restype1, thrown1, t.tsym); + } + + @Override + public Type visitCapturedType(CapturedType t, S s) { + return visitTypeVar(t, s); + } + + @Override + public Type visitForAll(ForAll t, S s) { + return visit(t.qtype, s); } } /** map a type function over all immediate descendants of this type */ - public Type map(Mapping f) { - return this; + public Type map(TypeMapping mapping, Z arg) { + return mapping.visit(this, arg); } - /** map a type function over a list of types + /** map a type function over all immediate descendants of this type (no arg version) */ - public static List map(List ts, Mapping f) { - if (ts.nonEmpty()) { - List tail1 = map(ts.tail, f); - Type t = f.apply(ts.head); - if (tail1 != ts.tail || t != ts.head) - return tail1.prepend(t); - } - return ts; + public Type map(TypeMapping mapping) { + return mapping.visit(this, null); } /** Define a constant type, of the same kind as this type @@ -775,17 +825,6 @@ return s.toString(); } - public Type map(Mapping f) { - //- System.err.println(" (" + this + ").map(" + f + ")");//DEBUG - Type t = type; - if (t != null) - t = f.apply(t); - if (t == type) - return this; - else - return new WildcardType(t, kind, tsym, bound, metadata); - } - @DefinedBy(Api.LANGUAGE_MODEL) public Type getExtendsBound() { if (kind == EXTENDS) @@ -1009,15 +1048,6 @@ allparams().isEmpty(); } - public Type map(Mapping f) { - Type outer = getEnclosingType(); - Type outer1 = f.apply(outer); - List typarams = getTypeArguments(); - List typarams1 = map(typarams, f); - if (outer1 == outer && typarams1 == typarams) return this; - else return new ClassType(outer1, typarams1, tsym, metadata); - } - public boolean contains(Type elem) { return elem == this @@ -1248,12 +1278,6 @@ }; } - public Type map(Mapping f) { - Type elemtype1 = f.apply(elemtype); - if (elemtype1 == elemtype) return this; - else return new ArrayType(elemtype1, tsym, metadata); - } - public boolean contains(Type elem) { return elem == this || elemtype.contains(elem); } @@ -1345,16 +1369,6 @@ restype != null && restype.isErroneous(); } - public Type map(Mapping f) { - List argtypes1 = map(argtypes, f); - Type restype1 = f.apply(restype); - List thrown1 = map(thrown, f); - if (argtypes1 == argtypes && - restype1 == restype && - thrown1 == thrown) return this; - else return new MethodType(argtypes1, restype1, thrown1, tsym); - } - public boolean contains(Type elem) { return elem == this || contains(argtypes, elem) || restype.contains(elem) || contains(thrown, elem); } @@ -1647,10 +1661,6 @@ return qtype.isErroneous(); } - public Type map(Mapping f) { - return f.apply(qtype); - } - public boolean contains(Type elem) { return qtype.contains(elem); } @@ -1820,7 +1830,7 @@ } protected void addBound(InferenceBound ib, Type bound, Types types, boolean update) { - Type bound2 = toTypeVarMap.apply(bound).baseType(); + Type bound2 = bound.map(toTypeVarMap).baseType(); List prevBounds = bounds.get(ib); for (Type b : prevBounds) { //check for redundancy - use strict version of isSameType on tvars @@ -1831,15 +1841,10 @@ notifyChange(EnumSet.of(ib)); } //where - Type.Mapping toTypeVarMap = new Mapping("toTypeVarMap") { + TypeMapping toTypeVarMap = new TypeMapping() { @Override - public Type apply(Type t) { - if (t.hasTag(UNDETVAR)) { - UndetVar uv = (UndetVar)t; - return uv.inst != null ? uv.inst : uv.qtype; - } else { - return t.map(this); - } + public Type visitUndetVar(UndetVar uv, Void _unused) { + return uv.inst != null ? uv.inst : uv.qtype; } }; @@ -2110,7 +2115,6 @@ public Type getEnclosingType() { return this; } public Type getReturnType() { return this; } public Type asSub(Symbol sym) { return this; } - public Type map(Mapping f) { return this; } public boolean isGenType(Type t) { return true; } public boolean isErroneous() { return true; } diff -r 4bfc61b8c9b0 -r 17efac395638 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java Thu Mar 19 12:59:26 2015 -0700 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java Thu Mar 19 16:13:40 2015 -0700 @@ -32,6 +32,8 @@ import java.util.Map; import java.util.Set; import java.util.WeakHashMap; +import java.util.function.BiPredicate; +import java.util.stream.Collector; import javax.tools.JavaFileObject; @@ -1766,10 +1768,11 @@ // public List cvarLowerBounds(List ts) { - return map(ts, cvarLowerBoundMapping); + return ts.map(cvarLowerBoundMapping); } - private final Mapping cvarLowerBoundMapping = new Mapping("cvarLowerBound") { - public Type apply(Type t) { + private final TypeMapping cvarLowerBoundMapping = new TypeMapping() { + @Override + public Type visitCapturedType(CapturedType t, Void _unused) { return cvarLowerBound(t); } }; @@ -1879,9 +1882,15 @@ /** * Mapping to take element type of an arraytype */ - private Mapping elemTypeFun = new Mapping ("elemTypeFun") { - public Type apply(Type t) { - return elemtype(skipTypeVars(t, false)); + private TypeMapping elemTypeFun = new TypeMapping() { + @Override + public Type visitArrayType(ArrayType t, Void _unused) { + return t.elemtype; + } + + @Override + public Type visitTypeVar(TypeVar t, Void _unused) { + return visit(skipTypeVars(t, false)); } }; @@ -2177,7 +2186,7 @@ } } // where - private SimpleVisitor erasure = new SimpleVisitor() { + private TypeMapping erasure = new TypeMapping() { private Type combineMetadata(final Type ty, final TypeMetadata md) { if (!md.isEmpty()) { @@ -2202,8 +2211,8 @@ if (t.isPrimitive()) return t; /*fast special case*/ else { - Type erased = t.map(recurse ? erasureRecFun : erasureFun); - return combineMetadata(erased, t.getMetadata()); + //other cases already handled + return combineMetadata(t, t.getMetadata()); } } @@ -2223,23 +2232,10 @@ Type erased = erasure(t.bound, recurse); return combineMetadata(erased, t.getMetadata()); } - - @Override - public Type visitErrorType(ErrorType t, Boolean recurse) { - return t; - } }; - private Mapping erasureFun = new Mapping ("erasure") { - public Type apply(Type t) { return erasure(t); } - }; - - private Mapping erasureRecFun = new Mapping ("erasureRecursive") { - public Type apply(Type t) { return erasureRecursive(t); } - }; - public List erasure(List ts) { - return Type.map(ts, erasureFun); + return erasure.visit(ts, false); } public Type erasureRecursive(Type t) { @@ -2247,7 +2243,7 @@ } public List erasureRecursive(List ts) { - return Type.map(ts, erasureRecFun); + return erasure.visit(ts, true); } // @@ -3177,15 +3173,18 @@ * changing all recursive bounds from old to new list. */ public List newInstances(List tvars) { - List tvars1 = Type.map(tvars, newInstanceFun); + List tvars1 = tvars.map(newInstanceFun); for (List l = tvars1; l.nonEmpty(); l = l.tail) { TypeVar tv = (TypeVar) l.head; tv.bound = subst(tv.bound, tvars, tvars1); } return tvars1; } - private static final Mapping newInstanceFun = new Mapping("newInstanceFun") { - public Type apply(Type t) { return new TypeVar(t.tsym, t.getUpperBound(), t.getLowerBound(), t.getMetadata()); } + private static final TypeMapping newInstanceFun = new TypeMapping() { + @Override + public TypeVar visitTypeVar(TypeVar t, Void _unused) { + return new TypeVar(t.tsym, t.getUpperBound(), t.getLowerBound(), t.getMetadata()); + } }; // @@ -3409,41 +3408,86 @@ } /** + * Collect types into a new closure (using a @code{ClosureHolder}) + */ + public Collector> closureCollector(boolean minClosure, BiPredicate shouldSkip) { + return Collector.of(() -> new ClosureHolder(minClosure, shouldSkip), + ClosureHolder::add, + ClosureHolder::merge, + ClosureHolder::closure); + } + //where + class ClosureHolder { + List closure; + final boolean minClosure; + final BiPredicate shouldSkip; + + ClosureHolder(boolean minClosure, BiPredicate shouldSkip) { + this.closure = List.nil(); + this.minClosure = minClosure; + this.shouldSkip = shouldSkip; + } + + void add(Type type) { + closure = insert(closure, type, shouldSkip); + } + + ClosureHolder merge(ClosureHolder other) { + closure = union(closure, other.closure, shouldSkip); + return this; + } + + List closure() { + return minClosure ? closureMin(closure) : closure; + } + } + + BiPredicate basicClosureSkip = (t1, t2) -> t1.tsym == t2.tsym; + + /** * Insert a type in a closure */ - public List insert(List cl, Type t) { + public List insert(List cl, Type t, BiPredicate shouldSkip) { if (cl.isEmpty()) { return cl.prepend(t); - } else if (t.tsym == cl.head.tsym) { + } else if (shouldSkip.test(t, cl.head)) { return cl; } else if (t.tsym.precedes(cl.head.tsym, this)) { return cl.prepend(t); } else { // t comes after head, or the two are unrelated - return insert(cl.tail, t).prepend(cl.head); + return insert(cl.tail, t, shouldSkip).prepend(cl.head); } } + public List insert(List cl, Type t) { + return insert(cl, t, basicClosureSkip); + } + /** * Form the union of two closures */ - public List union(List cl1, List cl2) { + public List union(List cl1, List cl2, BiPredicate shouldSkip) { if (cl1.isEmpty()) { return cl2; } else if (cl2.isEmpty()) { return cl1; - } else if (cl1.head.tsym == cl2.head.tsym) { - return union(cl1.tail, cl2.tail).prepend(cl1.head); + } else if (shouldSkip.test(cl1.head, cl2.head)) { + return union(cl1.tail, cl2.tail, shouldSkip).prepend(cl1.head); } else if (cl1.head.tsym.precedes(cl2.head.tsym, this)) { - return union(cl1.tail, cl2).prepend(cl1.head); + return union(cl1.tail, cl2, shouldSkip).prepend(cl1.head); } else if (cl2.head.tsym.precedes(cl1.head.tsym, this)) { - return union(cl1, cl2.tail).prepend(cl2.head); + return union(cl1, cl2.tail, shouldSkip).prepend(cl2.head); } else { // unrelated types - return union(cl1.tail, cl2).prepend(cl1.head); + return union(cl1.tail, cl2, shouldSkip).prepend(cl1.head); } } + public List union(List cl1, List cl2) { + return union(cl1, cl2, basicClosureSkip); + } + /** * Intersect two closures */ diff -r 4bfc61b8c9b0 -r 17efac395638 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java Thu Mar 19 12:59:26 2015 -0700 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java Thu Mar 19 16:13:40 2015 -0700 @@ -40,11 +40,13 @@ import com.sun.tools.javac.code.Scope.WriteableScope; import com.sun.tools.javac.code.Symbol.*; import com.sun.tools.javac.code.Type.*; +import com.sun.tools.javac.code.Types.FunctionDescriptorLookupError; import com.sun.tools.javac.comp.Check.CheckContext; import com.sun.tools.javac.comp.DeferredAttr.AttrMode; import com.sun.tools.javac.comp.Infer.InferenceContext; import com.sun.tools.javac.comp.Infer.FreeTypeListener; import com.sun.tools.javac.jvm.*; +import com.sun.tools.javac.resources.CompilerProperties.Fragments; import com.sun.tools.javac.tree.*; import com.sun.tools.javac.tree.JCTree.*; import com.sun.tools.javac.tree.JCTree.JCPolyExpression.*; @@ -2871,6 +2873,16 @@ names.empty, List.of(fExpr.targets.head), ABSTRACT); if (csym != null) { chk.checkImplementations(env.tree, csym, csym); + try { + //perform an additional functional interface check on the synthetic class, + //as there may be spurious errors for raw targets - because of existing issues + //with membership and inheritance (see JDK-8074570). + csym.flags_field |= INTERFACE; + types.findDescriptorType(csym.type); + } catch (FunctionDescriptorLookupError err) { + resultInfo.checkContext.report(fExpr, + diags.fragment(Fragments.NoSuitableFunctionalIntfInst(fExpr.targets.head))); + } } } catch (Types.FunctionDescriptorLookupError ex) { JCDiagnostic cause = ex.getDiagnostic(); @@ -2942,7 +2954,7 @@ public void visitBinary(JCBinary tree) { // Attribute arguments. Type left = chk.checkNonVoid(tree.lhs.pos(), attribExpr(tree.lhs, env)); - Type right = chk.checkNonVoid(tree.lhs.pos(), attribExpr(tree.rhs, env)); + Type right = chk.checkNonVoid(tree.rhs.pos(), attribExpr(tree.rhs, env)); // Find operator. Symbol operator = tree.operator = operators.resolveBinary(tree, tree.getTag(), left, right); Type owntype = types.createErrorType(tree.type); @@ -3722,7 +3734,7 @@ DeferredAttr.DeferredTypeMap checkDeferredMap = deferredAttr.new DeferredTypeMap(DeferredAttr.AttrMode.CHECK, sym, env.info.pendingResolutionPhase); - argtypes = Type.map(argtypes, checkDeferredMap); + argtypes = argtypes.map(checkDeferredMap); if (noteWarner.hasNonSilentLint(LintCategory.UNCHECKED)) { chk.warnUnchecked(env.tree.pos(), @@ -3730,7 +3742,7 @@ kindName(sym), sym.name, rs.methodArguments(sym.type.getParameterTypes()), - rs.methodArguments(Type.map(argtypes, checkDeferredMap)), + rs.methodArguments(argtypes.map(checkDeferredMap)), kindName(sym.location()), sym.location()); owntype = new MethodType(owntype.getParameterTypes(), @@ -3754,7 +3766,7 @@ return new Pair<>(sym, diag); } }; - List argtypes2 = Type.map(argtypes, + List argtypes2 = argtypes.map( rs.new ResolveDeferredRecoveryMap(AttrMode.CHECK, sym, env.info.pendingResolutionPhase)); JCDiagnostic errDiag = errSym.getDiagnostic(JCDiagnostic.DiagnosticType.ERROR, env.tree, sym, site, sym.name, argtypes2, typeargtypes); diff -r 4bfc61b8c9b0 -r 17efac395638 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/DeferredAttr.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/DeferredAttr.java Thu Mar 19 12:59:26 2015 -0700 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/DeferredAttr.java Thu Mar 19 16:13:40 2015 -0700 @@ -27,6 +27,7 @@ import com.sun.source.tree.LambdaExpressionTree.BodyKind; import com.sun.tools.javac.code.*; +import com.sun.tools.javac.code.Type.TypeMapping; import com.sun.tools.javac.comp.Resolve.ResolveError; import com.sun.tools.javac.resources.CompilerProperties.Fragments; import com.sun.tools.javac.tree.*; @@ -44,7 +45,6 @@ import java.util.ArrayList; import java.util.Collections; -import java.util.EnumMap; import java.util.EnumSet; import java.util.LinkedHashMap; import java.util.LinkedHashSet; @@ -300,13 +300,6 @@ } }; - DeferredTypeCompleter dummyCompleter = new DeferredTypeCompleter() { - public Type complete(DeferredType dt, ResultInfo resultInfo, DeferredAttrContext deferredAttrContext) { - Assert.check(deferredAttrContext.mode == AttrMode.CHECK); - return dt.tree.type = Type.stuckType; - } - }; - /** * Policy for detecting stuck expressions. Different criteria might cause * an expression to be judged as stuck, depending on whether the check @@ -849,33 +842,24 @@ /** an empty deferred attribution context - all methods throw exceptions */ final DeferredAttrContext emptyDeferredAttrContext; - /** The AttrMode to descriptive name mapping */ - private static final EnumMap deferredTypeMapDescriptions; - static { - deferredTypeMapDescriptions = new EnumMap<>(AttrMode.class); - deferredTypeMapDescriptions.put(AttrMode.CHECK, "deferredTypeMap[CHECK]"); - deferredTypeMapDescriptions.put(AttrMode.SPECULATIVE, "deferredTypeMap[SPECULATIVE]"); - } - /** * Map a list of types possibly containing one or more deferred types * into a list of ordinary types. Each deferred type D is mapped into a type T, * where T is computed by retrieving the type that has already been * computed for D during a previous deferred attribution round of the given kind. */ - class DeferredTypeMap extends Type.Mapping { + class DeferredTypeMap extends TypeMapping { DeferredAttrContext deferredAttrContext; protected DeferredTypeMap(AttrMode mode, Symbol msym, MethodResolutionPhase phase) { - super(deferredTypeMapDescriptions.get(mode)); this.deferredAttrContext = new DeferredAttrContext(mode, msym, phase, infer.emptyContext, emptyDeferredAttrContext, types.noWarnings); } @Override - public Type apply(Type t) { + public Type visitType(Type t, Void _unused) { if (!t.hasTag(DEFERRED)) { - return t.map(this); + return super.visitType(t, null); } else { DeferredType dt = (DeferredType)t; return typeOf(dt); @@ -928,7 +912,7 @@ return chk.checkNonVoid(pos, super.check(pos, found)); } }); - return super.apply(dt); + return super.visit(dt); } } diff -r 4bfc61b8c9b0 -r 17efac395638 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java Thu Mar 19 12:59:26 2015 -0700 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java Thu Mar 19 16:13:40 2015 -0700 @@ -25,6 +25,7 @@ package com.sun.tools.javac.comp; +import com.sun.tools.javac.code.Type.TypeMapping; import com.sun.tools.javac.tree.JCTree; import com.sun.tools.javac.tree.JCTree.JCTypeCast; import com.sun.tools.javac.tree.TreeInfo; @@ -477,7 +478,7 @@ restype = syms.objectType; } - List paramtypes = Type.map(argtypes, new ImplicitArgType(spMethod, resolveContext.step)); + List paramtypes = argtypes.map(new ImplicitArgType(spMethod, resolveContext.step)); List exType = spMethod != null ? spMethod.getThrownTypes() : List.of(syms.throwableType); // make it throw all exceptions @@ -495,9 +496,16 @@ (rs.deferredAttr).super(AttrMode.SPECULATIVE, msym, phase); } - public Type apply(Type t) { - t = types.erasure(super.apply(t)); - if (t.hasTag(BOT)) + @Override + public Type visitClassType(ClassType t, Void aVoid) { + return types.erasure(t); + } + + @Override + public Type visitType(Type t, Void _unused) { + if (t.hasTag(DEFERRED)) { + return visit(super.visitType(t, null)); + } else if (t.hasTag(BOT)) // nulls type as the marker type Null (which has no instances) // infer as java.lang.Void for now t = types.boxedClass(syms.voidType).type; @@ -865,7 +873,8 @@ @Override public void apply(UndetVar uv, InferenceContext inferenceContext, Warner warn) { Infer infer = inferenceContext.infer(); - List boundList = uv.getBounds(InferenceBound.UPPER); + List boundList = uv.getBounds(InferenceBound.UPPER).stream() + .collect(infer.types.closureCollector(true, infer.types::isSameType)); List boundListTail = boundList.tail; while (boundList.nonEmpty()) { List tmpTail = boundListTail; @@ -2046,23 +2055,19 @@ List freetypeListeners = List.nil(); public InferenceContext(List inferencevars) { - this.undetvars = Type.map(inferencevars, fromTypeVarFun); + this.undetvars = inferencevars.map(fromTypeVarFun); this.inferencevars = inferencevars; } //where - Mapping fromTypeVarFun = new Mapping("fromTypeVarFunWithBounds") { - // mapping that turns inference variables into undet vars - public Type apply(Type t) { - if (t.hasTag(TYPEVAR)) { - TypeVar tv = (TypeVar)t; - if (tv.isCaptured()) { - return new CapturedUndetVar((CapturedType)tv, types); - } else { - return new UndetVar(tv, types); - } - } else { - return t.map(this); - } + TypeMapping fromTypeVarFun = new TypeMapping() { + @Override + public Type visitTypeVar(TypeVar tv, Void aVoid) { + return new UndetVar(tv, types); + } + + @Override + public Type visitCapturedType(CapturedType t, Void aVoid) { + return new CapturedUndetVar(t, types); } }; diff -r 4bfc61b8c9b0 -r 17efac395638 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java Thu Mar 19 12:59:26 2015 -0700 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java Thu Mar 19 16:13:40 2015 -0700 @@ -232,8 +232,7 @@ } } String key = success ? "verbose.resolve.multi" : "verbose.resolve.multi.1"; - List argtypes2 = Type.map(argtypes, - deferredAttr.new RecoveryDeferredTypeMap(AttrMode.SPECULATIVE, bestSoFar, currentResolutionContext.step)); + List argtypes2 = argtypes.map(deferredAttr.new RecoveryDeferredTypeMap(AttrMode.SPECULATIVE, bestSoFar, currentResolutionContext.step)); JCDiagnostic main = diags.note(log.currentSource(), dpos, key, name, site.tsym, mostSpecificPos, currentResolutionContext.step, methodArguments(argtypes2), @@ -2259,7 +2258,7 @@ (typeargtypes == null || !Type.isErroneous(typeargtypes)); } public List getArgumentTypes(ResolveError errSym, Symbol accessedSym, Name name, List argtypes) { - return Type.map(argtypes, new ResolveDeferredRecoveryMap(AttrMode.SPECULATIVE, accessedSym, currentResolutionContext.step)); + return argtypes.map(new ResolveDeferredRecoveryMap(AttrMode.SPECULATIVE, accessedSym, currentResolutionContext.step)); } }; diff -r 4bfc61b8c9b0 -r 17efac395638 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java Thu Mar 19 12:59:26 2015 -0700 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java Thu Mar 19 16:13:40 2015 -0700 @@ -56,6 +56,7 @@ import static com.sun.tools.javac.code.Flags.*; import static com.sun.tools.javac.code.Kinds.Kind.*; +import static com.sun.tools.javac.code.TypeTag.ARRAY; import static com.sun.tools.javac.code.TypeTag.CLASS; import static com.sun.tools.javac.code.TypeTag.TYPEVAR; import static com.sun.tools.javac.jvm.ClassFile.*; @@ -2006,6 +2007,15 @@ } if (saveParameterNames) setParameterNames(m, type); + + if ((flags & VARARGS) != 0) { + final Type last = type.getParameterTypes().last(); + if (last == null || !last.hasTag(ARRAY)) { + m.flags_field &= ~VARARGS; + throw badClassFile("malformed.vararg.method", m); + } + } + return m; } diff -r 4bfc61b8c9b0 -r 17efac395638 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties Thu Mar 19 12:59:26 2015 -0700 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties Thu Mar 19 16:13:40 2015 -0700 @@ -1847,6 +1847,9 @@ compiler.misc.undecl.type.var=\ undeclared type variable: {0} +compiler.misc.malformed.vararg.method=\ + class file contains malformed variable arity method: {0} + compiler.misc.wrong.version=\ class file has wrong version {0}.{1}, should be {2}.{3} diff -r 4bfc61b8c9b0 -r 17efac395638 langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/util/List.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/util/List.java Thu Mar 19 12:59:26 2015 -0700 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/util/List.java Thu Mar 19 16:13:40 2015 -0700 @@ -33,6 +33,7 @@ import java.util.AbstractCollection; import java.util.ListIterator; import java.util.NoSuchElementException; +import java.util.function.Function; import java.util.stream.Collector; /** A class for generic linked lists. Links are supposed to be @@ -417,6 +418,17 @@ } @SuppressWarnings("unchecked") + public List map(Function mapper) { + if (nonEmpty()) { + List tail1 = tail.map(mapper); + Z head1 = mapper.apply(head); + if (tail1 != tail || head1 != head) + return tail1.prepend(head1); + } + return (List)this; + } + + @SuppressWarnings("unchecked") public static List convert(Class klass, List list) { if (list == null) return null; diff -r 4bfc61b8c9b0 -r 17efac395638 langtools/test/tools/javac/T8071847/T8071847.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/T8071847/T8071847.java Thu Mar 19 16:13:40 2015 -0700 @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2015, 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 8071847 + * @summary Verify proper termination when instance initialization method uses invalid flags + * @compile T8071847.java + * @run main T8071847 +*/ + + +import java.io.*; +import java.util.*; + +public class T8071847 { + String testclass="invalidFlags.class"; + String testclassHexString = + "CAFEBABE00000031000D0A0003000A07000B07000C0100063C696E69743E0100" + + "03282956010004436F646501000F4C696E654E756D6265725461626C6501000A" + + "536F7572636546696C65010009546573742E6A6176610C0004000501000C696E" + + "76616C6964466C6167730100106A6176612F6C616E672F4F626A656374002000" + + "02000300000000000100A000040005000100060000001D00010001000000052A" + + "B70001B10000000100070000000600010000000100010008000000020009"; + + String testJavaFile = "testInvalidFlags.java"; + String testJavaSource ="public class testInvalidFlags extends invalidFlags {" + + "invalidFlags c = null;" + + "public testInvalidFlags() { c = new invalidFlags(); }" + + "public static void main(String... args) { " + + "new testInvalidFlags();}}"; + + public static void main(String[] args) throws Exception { + new T8071847().run(); + } + + public void run() throws IOException { + writeHexFile(testclass,testclassHexString); + writeTestFile(testJavaFile, testJavaSource); + javac(testJavaFile); + } + + File writeTestFile(String fname, String source) throws IOException { + File f = new File(fname); + PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(f))); + out.println(source); + out.close(); + return f; + } + + byte[] hexToByte(String str) { + char[] CA = str.toCharArray(); + byte[] byteArry = new byte[str.length()/2]; + int bi = 0; + for (int i = 0; i javacArgs = new ArrayList<>(); + javacArgs.addAll(Arrays.asList("-XDrawDiagnostics", "-cp", ".", "-d", ".", className)); + rc = com.sun.tools.javac.Main.compile( + javacArgs.toArray(new String[javacArgs.size()]),out); + out.close(); + if (rc > 1) { + System.out.println(sw.toString()); + throw new Error("javac " + className + " failed. rc=" + rc); + } + if (rc != 1 || !sw.toString().contains("compiler.misc.malformed.vararg.method")) + throw new RuntimeException("Unexpected output" + sw.toString()); + return sw.toString(); + } +} diff -r 4bfc61b8c9b0 -r 17efac395638 langtools/test/tools/javac/diags/examples.not-yet.txt --- a/langtools/test/tools/javac/diags/examples.not-yet.txt Thu Mar 19 12:59:26 2015 -0700 +++ b/langtools/test/tools/javac/diags/examples.not-yet.txt Thu Mar 19 16:13:40 2015 -0700 @@ -87,6 +87,7 @@ compiler.misc.unable.to.access.file # ClassFile compiler.misc.undecl.type.var # ClassReader compiler.misc.unicode.str.not.supported # ClassReader +compiler.misc.malformed.vararg.method # ClassReader compiler.misc.verbose.retro # UNUSED compiler.misc.verbose.retro.with # UNUSED compiler.misc.verbose.retro.with.list # UNUSED diff -r 4bfc61b8c9b0 -r 17efac395638 langtools/test/tools/javac/expression/BinopVoidTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/expression/BinopVoidTest.java Thu Mar 19 16:13:40 2015 -0700 @@ -0,0 +1,14 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8074148 + * @summary Attr.visitBinary flags error at wrong position + * + * @compile/fail/ref=BinopVoidTest.out -XDrawDiagnostics BinopVoidTest.java + */ + +class BinopVoidTest { + void foo() {} + int x = 10 + foo(); + int y = foo() + 10; + int z = foo() + foo(); +} diff -r 4bfc61b8c9b0 -r 17efac395638 langtools/test/tools/javac/expression/BinopVoidTest.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/expression/BinopVoidTest.out Thu Mar 19 16:13:40 2015 -0700 @@ -0,0 +1,5 @@ +BinopVoidTest.java:11:21: compiler.err.void.not.allowed.here +BinopVoidTest.java:12:16: compiler.err.void.not.allowed.here +BinopVoidTest.java:13:16: compiler.err.void.not.allowed.here +BinopVoidTest.java:13:24: compiler.err.void.not.allowed.here +4 errors diff -r 4bfc61b8c9b0 -r 17efac395638 langtools/test/tools/javac/generics/inference/8048838/T8048838.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/generics/inference/8048838/T8048838.java Thu Mar 19 16:13:40 2015 -0700 @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2015, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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 8048838 + * @summary type inference performance regression + * @compile T8048838.java + */ +class T8048838 { + + + T1 foo(T1 x1, T2 x2, T3 x3, T4 x4, T5 x5, T6 x6, T7 x7, T8 x8, T9 x9, T10 x10, T11 x11, T12 x12, + T13 x13, T14 x14, T15 x15, T16 x16, T17 x17, T18 x18, T19 x19, T20 x20, T21 x21, T22 x22, + T23 x23, T24 x24, T25 x25, T26 x26, T27 x27, T28 x28, T29 x29, T30 x30, T31 x31, T32 x32, + T33 x33, T34 x34, T35 x35, T36 x36, T37 x37, T38 x38, T39 x39, T40 x40, T41 x41, T42 x42, + T43 x43, T44 x44, T45 x45, T46 x46, T47 x47, T48 x48, T49 x49, T50 x50, T51 x51, T52 x52, + T53 x53, T54 x54, T55 x55, T56 x56, T57 x57, T58 x58, T59 x59, T60 x60, T61 x61, T62 x62, + T63 x63, T64 x64, T65 x65, T66 x66, T67 x67, T68 x68, T69 x69, T70 x70, T71 x71, T72 x72, + T73 x73, T74 x74, T75 x75, T76 x76, T77 x77, T78 x78, T79 x79, T80 x80, T81 x81, T82 x82, + T83 x83, T84 x84, T85 x85, T86 x86, T87 x87, T88 x88, T89 x89, T90 x90, T91 x91, T92 x92, + T93 x93, T94 x94, T95 x95, T96 x96, T97 x97, T98 x98, T99 x99, T100 x100) { return null; } + + Object test() { + return foo(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, + 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, + 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, + 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, + 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100); // type inference expected + } +} diff -r 4bfc61b8c9b0 -r 17efac395638 langtools/test/tools/javac/lambda/8074381/T8074381a.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/lambda/8074381/T8074381a.java Thu Mar 19 16:13:40 2015 -0700 @@ -0,0 +1,33 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8074381 + * @summary java.lang.AssertionError during compiling + * @compile/fail/ref=T8074381a.out -XDrawDiagnostics T8074381a.java + */ +class T8074381a { + interface Sup { + boolean m(X x); + } + + interface Sub extends Sup { + boolean m(String s); + } + + void testRaw() { + Sub s1 = c -> true; + Sub s2 = Boolean::new; + Sub s3 = new Sub() { + @Override + public boolean m(String o) { return true; } + }; + } + + void testNonRaw() { + Sub s1 = c -> true; + Sub s2 = Boolean::new; + Sub s3 = new Sub() { + @Override + public boolean m(String o) { return true; } + }; + } +} diff -r 4bfc61b8c9b0 -r 17efac395638 langtools/test/tools/javac/lambda/8074381/T8074381a.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/lambda/8074381/T8074381a.out Thu Mar 19 16:13:40 2015 -0700 @@ -0,0 +1,4 @@ +T8074381a.java:17:18: compiler.err.prob.found.req: (compiler.misc.no.suitable.functional.intf.inst: T8074381a.Sub) +T8074381a.java:18:18: compiler.err.prob.found.req: (compiler.misc.no.suitable.functional.intf.inst: T8074381a.Sub) +T8074381a.java:19:28: compiler.err.does.not.override.abstract: compiler.misc.anonymous.class: T8074381a$1, m(java.lang.Object), T8074381a.Sup +3 errors diff -r 4bfc61b8c9b0 -r 17efac395638 langtools/test/tools/javac/lambda/8074381/T8074381b.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/lambda/8074381/T8074381b.java Thu Mar 19 16:13:40 2015 -0700 @@ -0,0 +1,44 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8074381 + * @summary java.lang.AssertionError during compiling + * @compile/fail/ref=T8074381b.out -XDrawDiagnostics T8074381b.java + */ +import java.util.function.BiConsumer; +import java.util.function.Consumer; + +class T8074381b { + + @SuppressWarnings("unchecked") + public Invocation resolve(Handler handler) { + return new Invocation((t) -> handler.handle((String) t)); + } + + public static class Handler { + public void handle(String s) { + System.out.println(s); + } + } + + public static class Invocation { + public final ThrowingConsumer consumer; + + public Invocation(final ThrowingConsumer consumer) { + this.consumer = consumer; + } + } + + @FunctionalInterface + public interface ThrowingConsumer extends BiConsumer> { + @Override + default void accept(final T elem, final Consumer errorHandler) { + try { + acceptThrows(elem); + } catch (final Throwable e) { + errorHandler.accept(e); + } + } + + void acceptThrows(T elem) throws Throwable; + } +} diff -r 4bfc61b8c9b0 -r 17efac395638 langtools/test/tools/javac/lambda/8074381/T8074381b.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/lambda/8074381/T8074381b.out Thu Mar 19 16:13:40 2015 -0700 @@ -0,0 +1,2 @@ +T8074381b.java:14:16: compiler.err.cant.apply.symbol: kindname.constructor, Invocation, T8074381b.ThrowingConsumer, @383, kindname.class, T8074381b.Invocation, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.no.suitable.functional.intf.inst: T8074381b.ThrowingConsumer)) +1 error