changeset 1593:5b858be3d094

Bug fixes: *) method call with bad qualifier generates NPE if argument is a method reference *) bad stuck check for method reference leads to javac crash
author mcimadamore
date Fri, 09 Nov 2012 14:17:32 +0000
parents dc6dec36396b
children 16dda9281400
files src/share/classes/com/sun/tools/javac/comp/Attr.java src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java test/tools/javac/lambda/MethodReference54.java test/tools/javac/lambda/MethodReference54.out test/tools/javac/lambda/TargetType50.java test/tools/javac/lambda/TargetType50.out
diffstat 6 files changed, 105 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/com/sun/tools/javac/comp/Attr.java	Thu Nov 08 17:17:10 2012 +0000
+++ b/src/share/classes/com/sun/tools/javac/comp/Attr.java	Fri Nov 09 14:17:32 2012 +0000
@@ -2513,7 +2513,7 @@
 
             if (desc.getReturnType() == Type.recoveryType) {
                 // stop here
-                result = that.type = types.createErrorType(target);
+                result = that.type = target;
                 return;
             }
 
--- a/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java	Thu Nov 08 17:17:10 2012 +0000
+++ b/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java	Fri Nov 09 14:17:32 2012 +0000
@@ -25,6 +25,8 @@
 
 package com.sun.tools.javac.comp;
 
+import com.sun.source.tree.MemberReferenceTree;
+
 import com.sun.tools.javac.code.*;
 import com.sun.tools.javac.tree.*;
 import com.sun.tools.javac.util.*;
@@ -46,7 +48,6 @@
 
 import static com.sun.tools.javac.code.TypeTags.*;
 import static com.sun.tools.javac.tree.JCTree.Tag.*;
-import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
 
 /**
  * This is an helper class that is used to perform deferred type-analysis.
@@ -181,7 +182,7 @@
             DeferredAttrContext deferredAttrContext =
                     resultInfo.checkContext.deferredAttrContext();
             Assert.check(deferredAttrContext != emptyDeferredAttrContext);
-            List<Type> stuckVars = stuckVars(tree, resultInfo);
+            List<Type> stuckVars = stuckVars(tree, env, resultInfo);
             if (stuckVars.nonEmpty()) {
                 deferredAttrContext.addDeferredAttrNode(this, resultInfo, stuckVars);
                 return Type.noType;
@@ -468,7 +469,7 @@
     public class RecoveryDeferredTypeMap extends DeferredTypeMap {
 
         public RecoveryDeferredTypeMap(AttrMode mode, Symbol msym, MethodResolutionPhase phase) {
-            super(mode, msym, phase);
+            super(mode, msym, phase != null ? phase : MethodResolutionPhase.BOX);
         }
 
         @Override
@@ -501,11 +502,11 @@
      * an AST node can be type-checked
      */
     @SuppressWarnings("fallthrough")
-    List<Type> stuckVars(JCTree tree, ResultInfo resultInfo) {
+    List<Type> stuckVars(JCTree tree, Env<AttrContext> env, ResultInfo resultInfo) {
         if (resultInfo.pt.tag == NONE || resultInfo.pt.isErroneous()) {
             return List.nil();
         } else {
-            StuckChecker sc = new StuckChecker(resultInfo);
+            StuckChecker sc = new StuckChecker(resultInfo, env);
             sc.scan(tree);
             return List.from(sc.stuckVars);
         }
@@ -523,6 +524,7 @@
         Filter<JCTree> treeFilter;
         Infer.InferenceContext inferenceContext;
         Set<Type> stuckVars = new LinkedHashSet<Type>();
+        Env<AttrContext> env;
 
         final Filter<JCTree> argsFilter = new Filter<JCTree>() {
             public boolean accepts(JCTree t) {
@@ -551,10 +553,11 @@
             }
         };
 
-        StuckChecker(ResultInfo resultInfo) {
+        StuckChecker(ResultInfo resultInfo, Env<AttrContext> env) {
             this.pt = resultInfo.pt;
             this.inferenceContext = resultInfo.checkContext.inferenceContext();
             this.treeFilter = argsFilter;
+            this.env = env;
         }
 
         @Override
@@ -604,9 +607,18 @@
             if (!types.isFunctionalInterface(pt.tsym)) {
                 return;
             }
+            
             Type descType = types.findDescriptorType(pt);
             List<Type> freeArgVars = inferenceContext.freeVarsIn(descType.getParameterTypes());
             stuckVars.addAll(freeArgVars);
+            
+            List<Type> freeReturnVars = inferenceContext.freeVarsIn(descType.getReturnType());
+            if (tree.getMode() == MemberReferenceTree.ReferenceMode.NEW && freeReturnVars.nonEmpty()) {
+                JCTree qualifierType = attribSpeculative(tree.getQualifierExpression(), env, attr.unknownTypeInfo);
+                if (qualifierType.type.tag == CLASS && qualifierType.type.isRaw()) {
+                    stuckVars.addAll(freeReturnVars);
+                }
+            }
         }
 
         @Override
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/MethodReference54.java	Fri Nov 09 14:17:32 2012 +0000
@@ -0,0 +1,40 @@
+/*
+ * 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 method call with bad qualifier generates NPE if argument is a method reference
+ * @compile/fail/ref=MethodReference54.out -XDrawDiagnostics MethodReference54.java
+ */
+class MethodReference54 {
+
+    interface SAM {
+        void m();
+    }
+
+    void test() {
+        nonExistent.m(MethodReference54::get);
+    }
+
+    static String get() { return ""; }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/MethodReference54.out	Fri Nov 09 14:17:32 2012 +0000
@@ -0,0 +1,2 @@
+MethodReference54.java:36:9: compiler.err.cant.resolve.location: kindname.variable, nonExistent, , , (compiler.misc.location: kindname.class, MethodReference54, null)
+1 error
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/TargetType50.java	Fri Nov 09 14:17:32 2012 +0000
@@ -0,0 +1,42 @@
+/*
+ * 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 bad stuck check for method reference leads to javac crash
+ * @compile/fail/ref=TargetType50.out -XDrawDiagnostics TargetType50.java
+ */
+class TargetType50 {
+
+    interface Factory<F> { 
+        F make();
+    }
+
+    static class Sink<T> { }
+
+    <Y, S extends Sink<Y>> void m(Factory<S> factory) {  }
+
+    void test() {
+        m(Sink::new);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/TargetType50.out	Fri Nov 09 14:17:32 2012 +0000
@@ -0,0 +1,2 @@
+TargetType50.java:40:9: compiler.err.cant.apply.symbol: kindname.method, m, TargetType50.Factory<S>, @1405, kindname.class, TargetType50, (compiler.misc.cyclic.inference: S)
+1 error