changeset 2600:5f1518156bac

Merge
author asaha
date Tue, 16 Sep 2014 13:59:19 -0700
parents 0f5dc6fb282b (current diff) 7c3d27120b92 (diff)
children 85e33a42e40b
files
diffstat 5 files changed, 168 insertions(+), 58 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/com/sun/tools/javac/comp/Attr.java	Thu Sep 11 15:33:00 2014 -0700
+++ b/src/share/classes/com/sun/tools/javac/comp/Attr.java	Tue Sep 16 13:59:19 2014 -0700
@@ -287,7 +287,7 @@
      *  @param env    The current environment.
      */
     boolean isAssignableAsBlankFinal(VarSymbol v, Env<AttrContext> env) {
-        Symbol owner = owner(env);
+        Symbol owner = env.info.scope.owner;
            // owner refers to the innermost variable, method or
            // initializer block declaration at this point.
         return
@@ -302,41 +302,6 @@
              ((v.flags() & STATIC) != 0) == Resolve.isStatic(env));
     }
 
-    /**
-     * Return the innermost enclosing owner symbol in a given attribution context
-     */
-    Symbol owner(Env<AttrContext> env) {
-        while (true) {
-            switch (env.tree.getTag()) {
-                case VARDEF:
-                    //a field can be owner
-                    VarSymbol vsym = ((JCVariableDecl)env.tree).sym;
-                    if (vsym.owner.kind == TYP) {
-                        return vsym;
-                    }
-                    break;
-                case METHODDEF:
-                    //method def is always an owner
-                    return ((JCMethodDecl)env.tree).sym;
-                case CLASSDEF:
-                    //class def is always an owner
-                    return ((JCClassDecl)env.tree).sym;
-                case BLOCK:
-                    //static/instance init blocks are owner
-                    Symbol blockSym = env.info.scope.owner;
-                    if ((blockSym.flags() & BLOCK) != 0) {
-                        return blockSym;
-                    }
-                    break;
-                case TOPLEVEL:
-                    //toplevel is always an owner (for pkge decls)
-                    return env.info.scope.owner;
-            }
-            Assert.checkNonNull(env.next);
-            env = env.next;
-        }
-    }
-
     /** Check that variable can be assigned to.
      *  @param pos    The current source code position.
      *  @param v      The assigned varaible
@@ -3660,7 +3625,7 @@
             // and are subject to definite assignment checking.
             if ((env.info.enclVar == v || v.pos > tree.pos) &&
                 v.owner.kind == TYP &&
-                canOwnInitializer(owner(env)) &&
+                enclosingInitEnv(env) != null &&
                 v.owner == env.info.scope.owner.enclClass() &&
                 ((v.flags() & STATIC) != 0) == Resolve.isStatic(env) &&
                 (!env.tree.hasTag(ASSIGN) ||
@@ -3680,6 +3645,36 @@
         }
 
         /**
+         * Returns the enclosing init environment associated with this env (if any). An init env
+         * can be either a field declaration env or a static/instance initializer env.
+         */
+        Env<AttrContext> enclosingInitEnv(Env<AttrContext> env) {
+            while (true) {
+                switch (env.tree.getTag()) {
+                    case VARDEF:
+                        JCVariableDecl vdecl = (JCVariableDecl)env.tree;
+                        if (vdecl.sym.owner.kind == TYP) {
+                            //field
+                            return env;
+                        }
+                        break;
+                    case BLOCK:
+                        if (env.next.tree.hasTag(CLASSDEF)) {
+                            //instance/static initializer
+                            return env;
+                        }
+                        break;
+                    case METHODDEF:
+                    case CLASSDEF:
+                    case TOPLEVEL:
+                        return null;
+                }
+                Assert.checkNonNull(env.next);
+                env = env.next;
+            }
+        }
+
+        /**
          * Check for illegal references to static members of enum.  In
          * an enum type, constructors and initializers may not
          * reference its static members unless they are constant.
@@ -3732,17 +3727,6 @@
                    v.name != names._class;
         }
 
-        /** Can the given symbol be the owner of code which forms part
-         *  if class initialization? This is the case if the symbol is
-         *  a type or field, or if the symbol is the synthetic method.
-         *  owning a block.
-         */
-        private boolean canOwnInitializer(Symbol sym) {
-            return
-                (sym.kind & (VAR | TYP)) != 0 ||
-                (sym.kind == MTH && (sym.flags() & BLOCK) != 0);
-        }
-
     Warner noteWarner = new Warner();
 
     /**
--- a/src/share/classes/com/sun/tools/javac/comp/Resolve.java	Thu Sep 11 15:33:00 2014 -0700
+++ b/src/share/classes/com/sun/tools/javac/comp/Resolve.java	Tue Sep 16 13:59:19 2014 -0700
@@ -3045,7 +3045,7 @@
         /**
          * Should lookup stop at given phase with given result
          */
-        protected boolean shouldStop(Symbol sym, MethodResolutionPhase phase) {
+        final boolean shouldStop(Symbol sym, MethodResolutionPhase phase) {
             return phase.ordinal() > maxPhase.ordinal() ||
                     sym.kind < ERRONEOUS || sym.kind == AMBIGUOUS;
         }
@@ -4228,15 +4228,39 @@
         VARARITY(true, true) {
             @Override
             public Symbol mergeResults(Symbol bestSoFar, Symbol sym) {
-                switch (sym.kind) {
-                    case WRONG_MTH:
-                        return (bestSoFar.kind == WRONG_MTH || bestSoFar.kind == WRONG_MTHS) ?
-                            bestSoFar :
-                            sym;
-                    case ABSENT_MTH:
-                        return bestSoFar;
-                    default:
-                        return sym;
+                //Check invariants (see {@code LookupHelper.shouldStop})
+                Assert.check(bestSoFar.kind >= ERRONEOUS && bestSoFar.kind != AMBIGUOUS);
+                if (sym.kind < ERRONEOUS) {
+                    //varargs resolution successful
+                    return sym;
+                } else {
+                    //pick best error
+                    switch (bestSoFar.kind) {
+                        case WRONG_MTH:
+                        case WRONG_MTHS:
+                            //Override previous errors if they were caused by argument mismatch.
+                            //This generally means preferring current symbols - but we need to pay
+                            //attention to the fact that the varargs lookup returns 'less' candidates
+                            //than the previous rounds, and adjust that accordingly.
+                            switch (sym.kind) {
+                                case WRONG_MTH:
+                                    //if the previous round matched more than one method, return that
+                                    //result instead
+                                    return bestSoFar.kind == WRONG_MTHS ?
+                                            bestSoFar : sym;
+                                case ABSENT_MTH:
+                                    //do not override erroneous symbol if the arity lookup did not
+                                    //match any method
+                                    return bestSoFar;
+                                case WRONG_MTHS:
+                                default:
+                                    //safe to override
+                                    return sym;
+                            }
+                        default:
+                            //otherwise, return first error
+                            return bestSoFar;
+                    }
                 }
             }
         };
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/8051958/T8051958.java	Tue Sep 16 13:59:19 2014 -0700
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2014, 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 8051958
+ * @summary Cannot assign a value to final variable in lambda
+ * @compile T8051958.java
+ */
+
+class T8051958 {
+    Runnable inst_r = ()-> {
+        final int x;
+        x = 1;
+    };
+
+    Runnable static_r = ()-> {
+        final int x;
+        x = 1;
+    };
+
+    {
+        Runnable inst_r = ()-> {
+            final int x;
+            x = 1;
+        };
+    }
+
+    static {
+        Runnable static_r = ()-> {
+            final int x;
+            x = 1;
+        };
+    }
+
+    void instTest() {
+        Runnable static_r = ()-> {
+            final int x;
+            x = 1;
+        };
+    }
+
+    static void staticTest() {
+        Runnable static_r = ()-> {
+            final int x;
+            x = 1;
+        };
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/varargs/8055514/T8055514.java	Tue Sep 16 13:59:19 2014 -0700
@@ -0,0 +1,26 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug     8055514
+ * @summary  Wrong, confusing error when non-static varargs referenced in static context
+ * @compile/fail/ref=T8055514.out -Xlint:varargs -Werror -XDrawDiagnostics T8055514.java
+ */
+class T8055514 {
+    void m(int... args) { }
+
+    void m2(int... args) { }
+    static void m2(String s) { }
+
+    void m3(int... args) { }
+    static void m3(String s) { }
+    static void m3(Runnable r) { }
+
+    void m4(int... args) { }
+    void m4(int i1, int i2, int i3) { }
+
+    static void test() {
+        m(1,2,3); //only one candidate (varargs) - varargs error wins
+        m2(1,2,3); //two candidates - only one applicable (varargs) - varargs error wins
+        m3(1,2,3); //three candidates - only one applicable (varargs) - varargs error wins
+        m4(1,2,3); //two candidates - both applicable - basic error wins
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/varargs/8055514/T8055514.out	Tue Sep 16 13:59:19 2014 -0700
@@ -0,0 +1,5 @@
+T8055514.java:21:9: compiler.err.non-static.cant.be.ref: kindname.method, m(int...)
+T8055514.java:22:9: compiler.err.non-static.cant.be.ref: kindname.method, m2(int...)
+T8055514.java:23:9: compiler.err.non-static.cant.be.ref: kindname.method, m3(int...)
+T8055514.java:24:9: compiler.err.non-static.cant.be.ref: kindname.method, m4(int,int,int)
+4 errors