changeset 1888:94993bc21d7a

8009154: Missing cast in method reference bridge leads to NoSuchMethodError
author mcimadamore
date Wed, 27 Feb 2013 18:09:19 +0000
parents b0d74332d31f
children 992e484da75e
files src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java test/tools/javac/lambda/MethodReference65.java
diffstat 2 files changed, 54 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java	Wed Feb 27 12:04:26 2013 +0000
+++ b/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java	Wed Feb 27 18:09:19 2013 +0000
@@ -771,7 +771,7 @@
                 //bridge method body generation - this can be either a method call or a
                 //new instance creation expression, depending on the member reference kind
                 JCExpression bridgeExpr = (tree.getMode() == ReferenceMode.INVOKE)
-                        ? bridgeExpressionInvoke(rcvr)
+                        ? bridgeExpressionInvoke(makeReceiver(rcvr))
                         : bridgeExpressionNew();
 
                 //the body is either a return expression containing a method call,
@@ -784,6 +784,16 @@
                 make.at(prevPos);
             }
         }
+        //where
+            private JCExpression makeReceiver(VarSymbol rcvr) {
+                if (rcvr == null) return null;
+                JCExpression rcvrExpr = make.Ident(rcvr);
+                Type rcvrType = tree.sym.enclClass().type;
+                if (!rcvr.type.tsym.isSubClass(rcvrType.tsym, types)) {
+                    rcvrExpr = make.TypeCast(make.Type(rcvrType), rcvrExpr).setType(rcvrType);
+                }
+                return rcvrExpr;
+            }
 
         /**
          * determine the receiver of the bridged method call - the receiver can
@@ -791,12 +801,12 @@
          * original qualifier expression is never used here, as it might refer
          * to symbols not available in the static context of the bridge
          */
-        private JCExpression bridgeExpressionInvoke(VarSymbol rcvr) {
+        private JCExpression bridgeExpressionInvoke(JCExpression rcvr) {
             JCExpression qualifier =
                     tree.sym.isStatic() ?
                         make.Type(tree.sym.owner.type) :
                         (rcvr != null) ?
-                            make.Ident(rcvr) :
+                            rcvr :
                             tree.getQualifierExpression();
 
             //create the qualifier expression
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/MethodReference65.java	Wed Feb 27 18:09:19 2013 +0000
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2013, 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 8009154
+ * @summary Missing cast in method reference bridge leads to NoSuchMethodError
+ */
+public class MethodReference65 {
+    
+    interface SAM<X> {
+        void m(X ss, String s);
+    }
+
+    void m(String... s) { }
+
+    public static void main(String[] args) {
+        SAM<MethodReference65> st = MethodReference65::m;
+        st.m(new MethodReference65(), "");
+    }
+}