Mercurial > hg > openjdk > lambda > langtools
changeset 1440:92ef69a3ba61 lambda-b50 lambda-b56
Conformance fix:
*) Remove contravariant subtyping from structural most specific check
Bug fix:
*) Non-effectively final method parameter can erroneoulsy be accessed within lambda
author | mcimadamore |
---|---|
date | Thu, 26 Jul 2012 13:26:58 +0100 |
parents | b12b45bd9855 |
children | a66c3c778a5f 722d9b5ac901 |
files | src/share/classes/com/sun/tools/javac/comp/Flow.java src/share/classes/com/sun/tools/javac/comp/Resolve.java test/tools/javac/lambda/EffectivelyFinal01.java test/tools/javac/lambda/EffectivelyFinal01.out test/tools/javac/lambda/MostSpecific05.java test/tools/javac/lambda/mostSpecific/StructuralMostSpecificTest.java |
diffstat | 6 files changed, 67 insertions(+), 33 deletions(-) [+] |
line wrap: on
line diff
--- a/src/share/classes/com/sun/tools/javac/comp/Flow.java Wed Jul 25 19:31:06 2012 +0100 +++ b/src/share/classes/com/sun/tools/javac/comp/Flow.java Thu Jul 26 13:26:58 2012 +0100 @@ -1332,6 +1332,10 @@ /** The next available variable sequence number. */ int nextadr; + + /** The first variable sequence number in a block that can return. + */ + int returnadr; /** The list of unreferenced automatic resources. */ @@ -1362,8 +1366,8 @@ @Override void markDead() { - inits.inclRange(firstadr, nextadr); - uninits.inclRange(firstadr, nextadr); + inits.inclRange(returnadr, nextadr); + uninits.inclRange(returnadr, nextadr); } /*-------------- Processing variables ----------------------*/ @@ -1622,6 +1626,7 @@ Bits uninitsPrev = uninits.dup(); int nextadrPrev = nextadr; int firstadrPrev = firstadr; + int returnadrPrev = returnadr; Lint lintPrev = lint; lint = lint.augment(tree.sym.attributes_field); @@ -1666,6 +1671,7 @@ uninits = uninitsPrev; nextadr = nextadrPrev; firstadr = firstadrPrev; + returnadr = returnadrPrev; lint = lintPrev; } } @@ -2055,8 +2061,10 @@ public void visitLambda(JCLambda tree) { Bits prevUninits = uninits; Bits prevInits = inits; + int returnadrPrev = returnadr; ListBuffer<AssignPendingExit> prevPending = pendingExits; try { + returnadr = nextadr; pendingExits = new ListBuffer<AssignPendingExit>(); for (List<JCVariableDecl> l = tree.params; l.nonEmpty(); l = l.tail) { JCVariableDecl def = l.head; @@ -2071,6 +2079,7 @@ } } finally { + returnadr = returnadrPrev; uninits = prevUninits; inits = prevInits; pendingExits = prevPending;
--- a/src/share/classes/com/sun/tools/javac/comp/Resolve.java Wed Jul 25 19:31:06 2012 +0100 +++ b/src/share/classes/com/sun/tools/javac/comp/Resolve.java Thu Jul 26 13:26:58 2012 +0100 @@ -1338,12 +1338,9 @@ return false; } - //contravariant most specific check for functional descriptor parameter types - for (Type arg_t : args_t) { - if (!types.isSubtypeUnchecked(arg_t, args_s.head)) { - return false; - } - args_s = args_s.tail; + //invariant most specific check for functional descriptor parameter types + if (!types.isSameTypes(args_t, args_s)) { + return false; } return true;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/lambda/EffectivelyFinal01.java Thu Jul 26 13:26:58 2012 +0100 @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2012, 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 + * @summary effectively final check fails on method parameter + * @compile/fail/ref=EffectivelyFinal01.out -XDrawDiagnostics EffectivelyFinal01.java + */ +class EffectivelyFinal01 { + + interface SAM { + Integer m(Integer i); + } + + void test(Integer nefPar) { + SAM s = (Integer h) -> { Integer k = 0; return k + h + nefPar; }; + nefPar++; //non-effectively final + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/lambda/EffectivelyFinal01.out Thu Jul 26 13:26:58 2012 +0100 @@ -0,0 +1,2 @@ +EffectivelyFinal01.java:36:65: compiler.err.cant.ref.non.effectively.final.var: nefPar, (compiler.misc.lambda) +1 error
--- a/test/tools/javac/lambda/MostSpecific05.java Wed Jul 25 19:31:06 2012 +0100 +++ b/test/tools/javac/lambda/MostSpecific05.java Thu Jul 26 13:26:58 2012 +0100 @@ -35,22 +35,22 @@ throw new AssertionError(); } - interface DoubleConverter<T> { - T map(double t); + interface ObjectConverter<T extends Object> { + T map(Object o); + } + + interface NumberConverter<T extends Number> { + T map(Object o); } - interface LongConverter<T> { - T map(long t); - } - - static class MyList<E> { - void map(DoubleConverter<? extends E> m) { assertTrue(true); } - void map(LongConverter<? extends E> m) { assertTrue(false); } + static class MyMapper<A extends Object, B extends Number> { + void map(ObjectConverter<? extends A> m) { assertTrue(false); } + void map(NumberConverter<? extends B> m) { assertTrue(true); } } public static void main(String[] args) { - MyList<String> ls = new MyList<String>(); - ls.map(e->""); + MyMapper<Number, Double> mm = new MyMapper<Number, Double>(); + mm.map(e->1.0); assertTrue(assertionCount == 1); } }
--- a/test/tools/javac/lambda/mostSpecific/StructuralMostSpecificTest.java Wed Jul 25 19:31:06 2012 +0100 +++ b/test/tools/javac/lambda/mostSpecific/StructuralMostSpecificTest.java Thu Jul 26 13:26:58 2012 +0100 @@ -83,19 +83,6 @@ ArgTypeKind(String typeStr) { this.argTypeStr = typeStr; } - - boolean moreGeneralThan(ArgTypeKind ak) { - return moreGeneralThan[ordinal()][ak.ordinal()]; - } - - static boolean[][] moreGeneralThan = { - // SHORT | INT | BOOLEAN | OBJECT | INTEGER | DOUBLE - /* SHORT */ { true , false , false , false , false , false }, - /* INT */ { true , true , false , false , false , false }, - /* BOOLEAN */ { false , false , true , false , false , false }, - /* OBJECT */ { false , false , false , true , true , true }, - /* INTEGER */ { false , false , false , false , true , false }, - /* DOUBLE */ { false , false , false , false , false , true } }; } enum ExceptionKind { @@ -280,7 +267,7 @@ if (!rk1.moreSpecificThan(rk2)) return false; - if (!ak1.moreGeneralThan(ak2)) + if (ak1 != ak2) return false; return true;