changeset 3412:f25395823aab

8038182: javac crash with FunctionDescriptorLookupError for invalid functional interface Reviewed-by: mcimadamore Contributed-by: maurizio.cimadamore@oracle.com, vicente.romero@oracle.com
author vromero
date Thu, 19 Jun 2014 15:39:37 +0100
parents c230fa74ef7b
children 8085359d9444
files src/share/classes/com/sun/tools/javac/code/Types.java src/share/classes/com/sun/tools/javac/comp/Attr.java test/tools/javac/lambda/T8038182/CrashFunctionDescriptorExceptionTest.java test/tools/javac/lambda/T8038182/CrashFunctionDescriptorExceptionTest.out
diffstat 4 files changed, 40 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/com/sun/tools/javac/code/Types.java	Wed Jun 18 14:58:16 2014 -0700
+++ b/src/share/classes/com/sun/tools/javac/code/Types.java	Thu Jun 19 15:39:37 2014 +0100
@@ -626,7 +626,7 @@
      * (ii) perform functional interface bridge calculation.
      */
     public ClassSymbol makeFunctionalInterfaceClass(Env<AttrContext> env, Name name, List<Type> targets, long cflags) {
-        if (targets.isEmpty() || !isFunctionalInterface(targets.head)) {
+        if (targets.isEmpty()) {
             return null;
         }
         Symbol descSym = findDescriptorSymbol(targets.head.tsym);
--- a/src/share/classes/com/sun/tools/javac/comp/Attr.java	Wed Jun 18 14:58:16 2014 -0700
+++ b/src/share/classes/com/sun/tools/javac/comp/Attr.java	Thu Jun 19 15:39:37 2014 +0100
@@ -3135,10 +3135,19 @@
             if (checkContext.deferredAttrContext().mode == DeferredAttr.AttrMode.CHECK &&
                     pt != Type.recoveryType) {
                 //check that functional interface class is well-formed
-                ClassSymbol csym = types.makeFunctionalInterfaceClass(env,
-                        names.empty, List.of(fExpr.targets.head), ABSTRACT);
-                if (csym != null) {
-                    chk.checkImplementations(env.tree, csym, csym);
+                try {
+                    /* Types.makeFunctionalInterfaceClass() may throw an exception
+                     * when it's executed post-inference. See the listener code
+                     * above.
+                     */
+                    ClassSymbol csym = types.makeFunctionalInterfaceClass(env,
+                            names.empty, List.of(fExpr.targets.head), ABSTRACT);
+                    if (csym != null) {
+                        chk.checkImplementations(env.tree, csym, csym);
+                    }
+                } catch (Types.FunctionDescriptorLookupError ex) {
+                    JCDiagnostic cause = ex.getDiagnostic();
+                    resultInfo.checkContext.report(env.tree, cause);
                 }
             }
         }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/T8038182/CrashFunctionDescriptorExceptionTest.java	Thu Jun 19 15:39:37 2014 +0100
@@ -0,0 +1,24 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8038182
+ * @summary javac crash with FunctionDescriptorLookupError for invalid functional interface
+ * @compile/fail/ref=CrashFunctionDescriptorExceptionTest.out -XDrawDiagnostics CrashFunctionDescriptorExceptionTest.java
+ */
+
+class CrashFunctionDescriptorExceptionTest {
+
+    @SuppressWarnings("unchecked")
+    void m () {
+        bar((B b) -> {});
+    }
+
+    <E extends A<E>> void bar(I<E> i) {}
+
+    class A<E> {}
+
+    class B<E> extends A<E> {}
+
+    interface I<E extends A<E>> {
+        void foo(E e);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/T8038182/CrashFunctionDescriptorExceptionTest.out	Thu Jun 19 15:39:37 2014 +0100
@@ -0,0 +1,2 @@
+CrashFunctionDescriptorExceptionTest.java:12:13: compiler.err.prob.found.req: (compiler.misc.no.suitable.functional.intf.inst: CrashFunctionDescriptorExceptionTest.I<CrashFunctionDescriptorExceptionTest.B>)
+1 error