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;