changeset 13790:42794e648cfe jdk-9+108

8150825: MethodHandles.tryFinally throws IndexOutOfBoundsException for non-conforming parameter lists Reviewed-by: redestad
author mhaupt
date Mon, 29 Feb 2016 14:16:20 +0100
parents 41e3c10db27a
children 2582665c63ce d6dbe934ed0f 1aaa07a97e58
files src/java.base/share/classes/java/lang/invoke/MethodHandles.java test/java/lang/invoke/T8139885.java
diffstat 2 files changed, 20 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/src/java.base/share/classes/java/lang/invoke/MethodHandles.java	Fri Feb 26 12:11:28 2016 +0100
+++ b/src/java.base/share/classes/java/lang/invoke/MethodHandles.java	Mon Feb 29 14:16:20 2016 +0100
@@ -4137,8 +4137,10 @@
         // The cleanup parameter list (minus the leading Throwable and result parameters) must be a sublist of the
         // target parameter list.
         int cleanupArgIndex = rtype == void.class ? 1 : 2;
-        if (!cleanupParamTypes.subList(cleanupArgIndex, cleanupParamTypes.size()).
-                equals(target.type().parameterList().subList(0, cleanupParamTypes.size() - cleanupArgIndex))) {
+        List<Class<?>> cleanupArgSuffix = cleanupParamTypes.subList(cleanupArgIndex, cleanupParamTypes.size());
+        List<Class<?>> targetParamTypes = target.type().parameterList();
+        if (targetParamTypes.size() < cleanupArgSuffix.size() ||
+                !cleanupArgSuffix.equals(targetParamTypes.subList(0, cleanupParamTypes.size() - cleanupArgIndex))) {
             throw misMatchedTypes("cleanup parameters after (Throwable,result) and target parameter list prefix",
                     cleanup.type(), target.type());
         }
--- a/test/java/lang/invoke/T8139885.java	Fri Feb 26 12:11:28 2016 +0100
+++ b/test/java/lang/invoke/T8139885.java	Mon Feb 29 14:16:20 2016 +0100
@@ -26,6 +26,7 @@
 /* @test
  * @bug 8139885
  * @bug 8143798
+ * @bug 8150825
  * @run testng/othervm -ea -esa test.java.lang.invoke.T8139885
  */
 
@@ -315,14 +316,17 @@
                 {intid, MethodHandles.identity(double.class)},
                 {intid, MethodHandles.dropArguments(intid, 0, String.class)},
                 {intid, MethodHandles.dropArguments(intid, 0, Throwable.class, double.class)},
-                {errTarget, errCleanup}
+                {errTarget, errCleanup},
+                {TryFinally.MH_voidTarget, TryFinally.MH_voidCleanup}
         };
         String[] messages = {
                 "target and return types must match: double != int",
                 "cleanup first argument and Throwable must match: (String,int)int != class java.lang.Throwable",
                 "cleanup second argument and target return type must match: (Throwable,double,int)int != int",
                 "cleanup parameters after (Throwable,result) and target parameter list prefix must match: " +
-                        errCleanup.type() + " != " + errTarget.type()
+                        errCleanup.type() + " != " + errTarget.type(),
+                "cleanup parameters after (Throwable,result) and target parameter list prefix must match: " +
+                        TryFinally.MH_voidCleanup.type() + " != " + TryFinally.MH_voidTarget.type()
         };
         for (int i = 0; i < cases.length; ++i) {
             boolean caught = false;
@@ -908,6 +912,10 @@
             return r + " (but " + first + " first)!";
         }
 
+        static void voidTarget() {}
+
+        static void voidCleanup(Throwable t, int a) {}
+
         static final Class<TryFinally> TRY_FINALLY = TryFinally.class;
 
         static final MethodType MT_greet = methodType(String.class, String.class);
@@ -916,6 +924,8 @@
         static final MethodType MT_printMore = methodType(void.class, Throwable.class, String.class);
         static final MethodType MT_greetMore = methodType(String.class, String.class, String.class);
         static final MethodType MT_exclaimMore = methodType(String.class, Throwable.class, String.class, String.class);
+        static final MethodType MT_voidTarget = methodType(void.class);
+        static final MethodType MT_voidCleanup = methodType(void.class, Throwable.class, int.class);
 
         static final MethodHandle MH_greet;
         static final MethodHandle MH_exclaim;
@@ -923,6 +933,8 @@
         static final MethodHandle MH_printMore;
         static final MethodHandle MH_greetMore;
         static final MethodHandle MH_exclaimMore;
+        static final MethodHandle MH_voidTarget;
+        static final MethodHandle MH_voidCleanup;
 
         static final MethodType MT_hello = methodType(String.class, String.class);
         static final MethodType MT_printHello = methodType(void.class, String.class);
@@ -936,6 +948,8 @@
                 MH_printMore = LOOKUP.findStatic(TRY_FINALLY, "printMore", MT_printMore);
                 MH_greetMore = LOOKUP.findStatic(TRY_FINALLY, "greetMore", MT_greetMore);
                 MH_exclaimMore = LOOKUP.findStatic(TRY_FINALLY, "exclaimMore", MT_exclaimMore);
+                MH_voidTarget = LOOKUP.findStatic(TRY_FINALLY, "voidTarget", MT_voidTarget);
+                MH_voidCleanup = LOOKUP.findStatic(TRY_FINALLY, "voidCleanup", MT_voidCleanup);
             } catch (Exception e) {
                 throw new ExceptionInInitializerError(e);
             }