changeset 2570:d3515520e68e jdk8u40-b08

Merge
author lana
date Thu, 25 Sep 2014 11:02:03 -0700
parents ed1a48bedfa8 (current diff) 0ff5e3f8df45 (diff)
children 8bb38a350722 31d2a837676f
files
diffstat 10 files changed, 249 insertions(+), 82 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java	Wed Sep 24 11:38:26 2014 -0700
+++ b/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java	Thu Sep 25 11:02:03 2014 -0700
@@ -497,13 +497,11 @@
                     }
                 }
                 if (!progress) {
-                    DeferredAttrContext dac = this;
-                    while (dac != emptyDeferredAttrContext) {
-                        if (dac.mode == AttrMode.SPECULATIVE) {
-                            //unsticking does not take place during overload
-                            break;
+                    if (insideOverloadPhase()) {
+                        for (DeferredAttrNode deferredNode: deferredAttrNodes) {
+                            deferredNode.dt.tree.type = Type.noType;
                         }
-                        dac = dac.parent;
+                        return;
                     }
                     //remove all variables that have already been instantiated
                     //from the list of stuck variables
@@ -519,6 +517,17 @@
                 }
             }
         }
+
+        private boolean insideOverloadPhase() {
+            DeferredAttrContext dac = this;
+            if (dac == emptyDeferredAttrContext) {
+                return false;
+            }
+            if (dac.mode == AttrMode.SPECULATIVE) {
+                return true;
+            }
+            return dac.parent.insideOverloadPhase();
+        }
     }
 
     /**
@@ -579,6 +588,8 @@
                             return false;
                         }
                     } else {
+                        Assert.check(!deferredAttrContext.insideOverloadPhase(),
+                                "attribution shouldn't be happening here");
                         ResultInfo instResultInfo =
                                 resultInfo.dup(deferredAttrContext.inferenceContext.asInstType(resultInfo.pt));
                         dt.check(instResultInfo, dummyStuckPolicy, basicCompleter);
@@ -1314,6 +1325,12 @@
                 site = env.enclClass.sym.type;
             }
 
+            while (site.hasTag(TYPEVAR)) {
+                site = site.getUpperBound();
+            }
+
+            site = types.capture(site);
+
             List<Type> args = rs.dummyArgs(tree.args.length());
             Name name = TreeInfo.name(tree.meth);
 
@@ -1337,7 +1354,9 @@
                 @Override
                 public Symbol process(MethodSymbol ms) {
                     ArgumentExpressionKind kind = ArgumentExpressionKind.methodKind(ms, types);
-                    return kind != ArgumentExpressionKind.POLY ? ms.getReturnType().tsym : null;
+                    if (kind == ArgumentExpressionKind.POLY || ms.getReturnType().hasTag(TYPEVAR))
+                        return null;
+                    return ms.getReturnType().tsym;
                 }
                 @Override
                 public Symbol reduce(Symbol s1, Symbol s2) {
--- a/src/share/classes/com/sun/tools/javac/comp/Flow.java	Wed Sep 24 11:38:26 2014 -0700
+++ b/src/share/classes/com/sun/tools/javac/comp/Flow.java	Thu Sep 25 11:02:03 2014 -0700
@@ -208,7 +208,7 @@
 
     public void analyzeTree(Env<AttrContext> env, TreeMaker make) {
         new AliveAnalyzer().analyzeTree(env, make);
-        new AssignAnalyzer(log, syms, lint, names, enforceThisDotInit).analyzeTree(env);
+        new AssignAnalyzer().analyzeTree(env);
         new FlowAnalyzer().analyzeTree(env, make);
         new CaptureAnalyzer().analyzeTree(env, make);
     }
@@ -241,7 +241,7 @@
         //related errors, which will allow for more errors to be detected
         Log.DiagnosticHandler diagHandler = new Log.DiscardDiagnosticHandler(log);
         try {
-            new AssignAnalyzer(log, syms, lint, names, enforceThisDotInit) {
+            new AssignAnalyzer() {
                 @Override
                 protected boolean trackable(VarSymbol sym) {
                     return !env.info.scope.includes(sym) &&
@@ -1373,12 +1373,12 @@
      * effectively-final local variables/parameters.
      */
 
-    public abstract static class AbstractAssignAnalyzer<P extends AbstractAssignAnalyzer.AbstractAssignPendingExit>
+    public abstract class AbstractAssignAnalyzer<P extends AbstractAssignAnalyzer<P>.AbstractAssignPendingExit>
         extends BaseAnalyzer<P> {
 
         /** The set of definitely assigned variables.
          */
-        protected final Bits inits;
+        protected Bits inits;
 
         /** The set of definitely unassigned variables.
          */
@@ -1432,13 +1432,7 @@
         /** The starting position of the analysed tree */
         int startPos;
 
-        final Symtab syms;
-
-        protected Names names;
-
-        final boolean enforceThisDotInit;
-
-        public static class AbstractAssignPendingExit extends BaseAnalyzer.PendingExit {
+        public class AbstractAssignPendingExit extends BaseAnalyzer.PendingExit {
 
             final Bits inits;
             final Bits uninits;
@@ -1460,17 +1454,14 @@
             }
         }
 
-        public AbstractAssignAnalyzer(Bits inits, Symtab syms, Names names, boolean enforceThisDotInit) {
-            this.inits = inits;
+        public AbstractAssignAnalyzer() {
+            this.inits = new Bits();
             uninits = new Bits();
             uninitsTry = new Bits();
             initsWhenTrue = new Bits(true);
             initsWhenFalse = new Bits(true);
             uninitsWhenTrue = new Bits(true);
             uninitsWhenFalse = new Bits(true);
-            this.syms = syms;
-            this.names = names;
-            this.enforceThisDotInit = enforceThisDotInit;
         }
 
         private boolean isInitialConstructor = false;
@@ -2439,26 +2430,15 @@
         }
     }
 
-    public static class AssignAnalyzer
-        extends AbstractAssignAnalyzer<AssignAnalyzer.AssignPendingExit> {
+    public class AssignAnalyzer extends AbstractAssignAnalyzer<AssignAnalyzer.AssignPendingExit> {
 
-        Log log;
-        Lint lint;
-
-        public static class AssignPendingExit
-            extends AbstractAssignAnalyzer.AbstractAssignPendingExit {
+        public class AssignPendingExit extends AbstractAssignAnalyzer<AssignPendingExit>.AbstractAssignPendingExit {
 
             public AssignPendingExit(JCTree tree, final Bits inits, final Bits uninits) {
                 super(tree, inits, uninits);
             }
         }
 
-        public AssignAnalyzer(Log log, Symtab syms, Lint lint, Names names, boolean enforceThisDotInit) {
-            super(new Bits(), syms, names, enforceThisDotInit);
-            this.log = log;
-            this.lint = lint;
-        }
-
         @Override
         protected AssignPendingExit createNewPendingExit(JCTree tree,
             Bits inits, Bits uninits) {
--- a/src/share/classes/com/sun/tools/javac/jvm/Gen.java	Wed Sep 24 11:38:26 2014 -0700
+++ b/src/share/classes/com/sun/tools/javac/jvm/Gen.java	Thu Sep 25 11:02:03 2014 -0700
@@ -74,6 +74,7 @@
     private Name accessDollar;
     private final Types types;
     private final Lower lower;
+    private final Flow flow;
 
     /** Switch: GJ mode?
      */
@@ -125,6 +126,7 @@
         stringBufferAppend = new HashMap<Type,Symbol>();
         accessDollar = names.
             fromString("access" + target.syntheticNameChar());
+        flow = Flow.instance(context);
         lower = Lower.instance(context);
 
         Options options = Options.instance(context);
@@ -2516,9 +2518,7 @@
              */
             if (varDebugInfo && (cdef.sym.flags() & SYNTHETIC) == 0) {
                 try {
-                    LVTAssignAnalyzer lvtAssignAnalyzer = LVTAssignAnalyzer.make(
-                            lvtRanges, syms, names);
-                    lvtAssignAnalyzer.analyzeTree(localEnv);
+                    new LVTAssignAnalyzer().analyzeTree(localEnv);
                 } catch (Throwable e) {
                     throw e;
                 }
@@ -2609,11 +2609,10 @@
         }
     }
 
-    static class LVTAssignAnalyzer
+    class LVTAssignAnalyzer
         extends Flow.AbstractAssignAnalyzer<LVTAssignAnalyzer.LVTAssignPendingExit> {
 
         final LVTBits lvtInits;
-        final LVTRanges lvtRanges;
 
         /*  This class is anchored to a context dependent tree. The tree can
          *  vary inside the same instruction for example in the switch instruction
@@ -2621,35 +2620,12 @@
          *  to a given case. The aim is to always anchor the bits to the tree
          *  capable of closing a DA range.
          */
-        static class LVTBits extends Bits {
-
-            enum BitsOpKind {
-                INIT,
-                CLEAR,
-                INCL_BIT,
-                EXCL_BIT,
-                ASSIGN,
-                AND_SET,
-                OR_SET,
-                DIFF_SET,
-                XOR_SET,
-                INCL_RANGE,
-                EXCL_RANGE,
-            }
+        class LVTBits extends Bits {
 
             JCTree currentTree;
-            LVTAssignAnalyzer analyzer;
             private int[] oldBits = null;
             BitsState stateBeforeOp;
 
-            LVTBits() {
-                super(false);
-            }
-
-            LVTBits(int[] bits, BitsState initState) {
-                super(bits, initState);
-            }
-
             @Override
             public void clear() {
                 generalOp(null, -1, BitsOpKind.CLEAR);
@@ -2757,12 +2733,11 @@
                 if (currentTree != null &&
                         stateBeforeOp != BitsState.UNKNOWN &&
                         trackTree(currentTree)) {
-                    List<VarSymbol> locals =
-                            analyzer.lvtRanges
-                            .getVars(analyzer.currentMethod, currentTree);
+                    List<VarSymbol> locals = lvtRanges
+                            .getVars(currentMethod, currentTree);
                     locals = locals != null ?
                             locals : List.<VarSymbol>nil();
-                    for (JCVariableDecl vardecl : analyzer.vardecls) {
+                    for (JCVariableDecl vardecl : vardecls) {
                         //once the first is null, the rest will be so.
                         if (vardecl == null) {
                             break;
@@ -2772,7 +2747,7 @@
                         }
                     }
                     if (!locals.isEmpty()) {
-                        analyzer.lvtRanges.setEntry(analyzer.currentMethod,
+                        lvtRanges.setEntry(currentMethod,
                                 currentTree, locals);
                     }
                 }
@@ -2790,7 +2765,7 @@
             boolean trackVar(VarSymbol var) {
                 return (var.owner.kind == MTH &&
                         (var.flags() & PARAMETER) == 0 &&
-                        analyzer.trackable(var));
+                        trackable(var));
             }
 
             boolean trackTree(JCTree tree) {
@@ -2806,7 +2781,8 @@
 
         }
 
-        public class LVTAssignPendingExit extends Flow.AssignAnalyzer.AssignPendingExit {
+        public class LVTAssignPendingExit extends
+                                    Flow.AbstractAssignAnalyzer<LVTAssignPendingExit>.AbstractAssignPendingExit {
 
             LVTAssignPendingExit(JCTree tree, final Bits inits, final Bits uninits) {
                 super(tree, inits, uninits);
@@ -2819,16 +2795,10 @@
             }
         }
 
-        private LVTAssignAnalyzer(LVTRanges lvtRanges, Symtab syms, Names names) {
-            super(new LVTBits(), syms, names, false);
-            lvtInits = (LVTBits)inits;
-            this.lvtRanges = lvtRanges;
-        }
-
-        public static LVTAssignAnalyzer make(LVTRanges lvtRanges, Symtab syms, Names names) {
-            LVTAssignAnalyzer result = new LVTAssignAnalyzer(lvtRanges, syms, names);
-            result.lvtInits.analyzer = result;
-            return result;
+        private LVTAssignAnalyzer() {
+            flow.super();
+            lvtInits = new LVTBits();
+            inits = lvtInits;
         }
 
         @Override
--- a/src/share/classes/com/sun/tools/javac/util/Bits.java	Wed Sep 24 11:38:26 2014 -0700
+++ b/src/share/classes/com/sun/tools/javac/util/Bits.java	Thu Sep 25 11:02:03 2014 -0700
@@ -84,6 +84,20 @@
 
     }
 
+    public enum BitsOpKind {
+        INIT,
+        CLEAR,
+        INCL_BIT,
+        EXCL_BIT,
+        ASSIGN,
+        AND_SET,
+        OR_SET,
+        DIFF_SET,
+        XOR_SET,
+        INCL_RANGE,
+        EXCL_RANGE,
+    }
+
     private final static int wordlen = 32;
     private final static int wordshift = 5;
     private final static int wordmask = wordlen - 1;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/T8033483/IgnoreLambdaBodyDuringResolutionTest1.java	Thu Sep 25 11:02:03 2014 -0700
@@ -0,0 +1,31 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8033483
+ * @summary Should ignore nested lambda bodies during overload resolution
+ * @compile/fail/ref=IgnoreLambdaBodyDuringResolutionTest1.out -XDrawDiagnostics IgnoreLambdaBodyDuringResolutionTest1.java
+ */
+
+class IgnoreLambdaBodyDuringResolutionTest1 {
+    interface SAM<T> {
+        T action(T t);
+    }
+
+    <T> T m(SAM<T> op) {
+        return null;
+    }
+
+    class B {
+        B x() {
+            return this;
+        }
+    }
+
+    class C {}
+
+    void foo(B arg) {}
+    void foo(C arg) {}
+
+    void bar() {
+        foo(m(arg -> new B()));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/T8033483/IgnoreLambdaBodyDuringResolutionTest1.out	Thu Sep 25 11:02:03 2014 -0700
@@ -0,0 +1,2 @@
+IgnoreLambdaBodyDuringResolutionTest1.java:29:9: compiler.err.ref.ambiguous: foo, kindname.method, foo(IgnoreLambdaBodyDuringResolutionTest1.B), IgnoreLambdaBodyDuringResolutionTest1, kindname.method, foo(IgnoreLambdaBodyDuringResolutionTest1.C), IgnoreLambdaBodyDuringResolutionTest1
+1 error
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/T8033483/IgnoreLambdaBodyDuringResolutionTest2.java	Thu Sep 25 11:02:03 2014 -0700
@@ -0,0 +1,34 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8033483
+ * @summary Should ignore nested lambda bodies during overload resolution
+ * @compile/fail/ref=IgnoreLambdaBodyDuringResolutionTest2.out -XDrawDiagnostics IgnoreLambdaBodyDuringResolutionTest2.java
+ */
+
+class IgnoreLambdaBodyDuringResolutionTest2 {
+    interface SAM<S> {
+        boolean test(S t);
+    }
+
+    <I, T extends I> I bar(final T l) {
+        return null;
+    }
+
+    class D<D1, D2> {
+        void foo() {
+            m(bar(e -> false));
+        }
+
+        void m(Class<D1> arg) {}
+        void m(SAM<D2> arg) {}
+    }
+
+    class F {
+        void foo() {
+            m(bar((String e) -> false));
+        }
+
+        <F1> void m(Class<F1> arg) {}
+        <F2> void m(SAM<F2> arg) {}
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/T8033483/IgnoreLambdaBodyDuringResolutionTest2.out	Thu Sep 25 11:02:03 2014 -0700
@@ -0,0 +1,6 @@
+IgnoreLambdaBodyDuringResolutionTest2.java:19:13: compiler.err.ref.ambiguous: m, kindname.method, m(java.lang.Class<D1>), IgnoreLambdaBodyDuringResolutionTest2.D, kindname.method, m(IgnoreLambdaBodyDuringResolutionTest2.SAM<D2>), IgnoreLambdaBodyDuringResolutionTest2.D
+IgnoreLambdaBodyDuringResolutionTest2.java:19:18: compiler.err.prob.found.req: (compiler.misc.infer.no.conforming.assignment.exists: I,T, (compiler.misc.not.a.functional.intf: java.lang.Object))
+IgnoreLambdaBodyDuringResolutionTest2.java:19:14: compiler.err.cant.apply.symbol: kindname.method, m, java.lang.Class<D1>, <any>, kindname.class, IgnoreLambdaBodyDuringResolutionTest2.D<D1,D2>, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.infer.no.conforming.assignment.exists: I,T, (compiler.misc.not.a.functional.intf: java.lang.Class)))
+IgnoreLambdaBodyDuringResolutionTest2.java:28:13: compiler.err.ref.ambiguous: m, kindname.method, <F1>m(java.lang.Class<F1>), IgnoreLambdaBodyDuringResolutionTest2.F, kindname.method, <F2>m(IgnoreLambdaBodyDuringResolutionTest2.SAM<F2>), IgnoreLambdaBodyDuringResolutionTest2.F
+IgnoreLambdaBodyDuringResolutionTest2.java:28:14: compiler.err.prob.found.req: (compiler.misc.infer.no.conforming.assignment.exists: I,T, (compiler.misc.not.a.functional.intf: java.lang.Class))
+5 errors
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/T8056014.java	Thu Sep 25 11:02:03 2014 -0700
@@ -0,0 +1,70 @@
+/*
+ * 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.
+ *
+ * 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 8056014
+ * @summary Verify that full type inference is used when calling a method on a type variable.
+ * @compile T8056014.java
+ * @run main T8056014
+ */
+
+import java.util.*;
+
+public class T8056014 {
+    public static void main(String[] args) {
+        new T8056014().run();
+    }
+
+    void run() {
+        List<S> l = Arrays.asList(new S());
+        C<S> c = new C<>(new S());
+        foo(l.get(0).copy(1));
+        foo(c.get(0).copy(1));
+    }
+
+    void foo(S d) {
+    }
+}
+
+class B {
+    public B copy(long j) {
+        throw new AssertionError("Should not get here.");
+    }
+}
+
+class S extends B {
+    public <T> T copy(int i) {
+        return null;
+    }
+}
+
+class C<T extends B> {
+    final T t;
+    public C(T t) {
+        this.t = t;
+    }
+    public T get(int i) {
+        return t;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/T8056984.java	Thu Sep 25 11:02:03 2014 -0700
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ *
+ * 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 8056984
+ * @summary Ensure that method resolution runs over a captured type variables when checking if
+ *          deferred attribution is needed
+ * @compile T8056984.java
+ */
+class T8056984<T1 extends B&C, T2 extends T1> {
+    public T8056984(T1 t1, T2 t2) {
+        System.err.println(t1.hashCode());
+        System.err.println(t2.hashCode());
+    }
+}
+class B {
+}
+interface C {
+    public int hashCode();
+}