changeset 1952:a708c5f1da06

8009154: Missing cast in method reference bridge leads to NoSuchMethodError Summary: Missing cast in generated method reference bridge Reviewed-by: rfield, jjg
author mcimadamore
date Tue, 05 Mar 2013 14:16:07 +0000
parents d2a98dde7ecc
children 12202e6ab78a
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	Tue Mar 05 14:12:07 2013 +0000
+++ b/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java	Tue Mar 05 14:16:07 2013 +0000
@@ -774,7 +774,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,
@@ -787,6 +787,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
@@ -794,12 +804,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	Tue Mar 05 14:16:07 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(), "");
+    }
+}