Thu, 19 Jun 2014 15:39:37 +0100
8038182: javac crash with FunctionDescriptorLookupError for invalid functional interface
Reviewed-by: mcimadamore
Contributed-by: maurizio.cimadamore@oracle.com, vicente.romero@oracle.com
1.1 --- a/src/share/classes/com/sun/tools/javac/code/Types.java Wed Jun 18 10:44:16 2014 +0200 1.2 +++ b/src/share/classes/com/sun/tools/javac/code/Types.java Thu Jun 19 15:39:37 2014 +0100 1.3 @@ -629,7 +629,7 @@ 1.4 * (ii) perform functional interface bridge calculation. 1.5 */ 1.6 public ClassSymbol makeFunctionalInterfaceClass(Env<AttrContext> env, Name name, List<Type> targets, long cflags) { 1.7 - if (targets.isEmpty() || !isFunctionalInterface(targets.head)) { 1.8 + if (targets.isEmpty()) { 1.9 return null; 1.10 } 1.11 Symbol descSym = findDescriptorSymbol(targets.head.tsym);
2.1 --- a/src/share/classes/com/sun/tools/javac/comp/Attr.java Wed Jun 18 10:44:16 2014 +0200 2.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Attr.java Thu Jun 19 15:39:37 2014 +0100 2.3 @@ -2968,10 +2968,19 @@ 2.4 if (checkContext.deferredAttrContext().mode == DeferredAttr.AttrMode.CHECK && 2.5 pt != Type.recoveryType) { 2.6 //check that functional interface class is well-formed 2.7 - ClassSymbol csym = types.makeFunctionalInterfaceClass(env, 2.8 - names.empty, List.of(fExpr.targets.head), ABSTRACT); 2.9 - if (csym != null) { 2.10 - chk.checkImplementations(env.tree, csym, csym); 2.11 + try { 2.12 + /* Types.makeFunctionalInterfaceClass() may throw an exception 2.13 + * when it's executed post-inference. See the listener code 2.14 + * above. 2.15 + */ 2.16 + ClassSymbol csym = types.makeFunctionalInterfaceClass(env, 2.17 + names.empty, List.of(fExpr.targets.head), ABSTRACT); 2.18 + if (csym != null) { 2.19 + chk.checkImplementations(env.tree, csym, csym); 2.20 + } 2.21 + } catch (Types.FunctionDescriptorLookupError ex) { 2.22 + JCDiagnostic cause = ex.getDiagnostic(); 2.23 + resultInfo.checkContext.report(env.tree, cause); 2.24 } 2.25 } 2.26 }
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 3.2 +++ b/test/tools/javac/lambda/T8038182/CrashFunctionDescriptorExceptionTest.java Thu Jun 19 15:39:37 2014 +0100 3.3 @@ -0,0 +1,24 @@ 3.4 +/* 3.5 + * @test /nodynamiccopyright/ 3.6 + * @bug 8038182 3.7 + * @summary javac crash with FunctionDescriptorLookupError for invalid functional interface 3.8 + * @compile/fail/ref=CrashFunctionDescriptorExceptionTest.out -XDrawDiagnostics CrashFunctionDescriptorExceptionTest.java 3.9 + */ 3.10 + 3.11 +class CrashFunctionDescriptorExceptionTest { 3.12 + 3.13 + @SuppressWarnings("unchecked") 3.14 + void m () { 3.15 + bar((B b) -> {}); 3.16 + } 3.17 + 3.18 + <E extends A<E>> void bar(I<E> i) {} 3.19 + 3.20 + class A<E> {} 3.21 + 3.22 + class B<E> extends A<E> {} 3.23 + 3.24 + interface I<E extends A<E>> { 3.25 + void foo(E e); 3.26 + } 3.27 +}
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 4.2 +++ b/test/tools/javac/lambda/T8038182/CrashFunctionDescriptorExceptionTest.out Thu Jun 19 15:39:37 2014 +0100 4.3 @@ -0,0 +1,2 @@ 4.4 +CrashFunctionDescriptorExceptionTest.java:12:13: compiler.err.prob.found.req: (compiler.misc.no.suitable.functional.intf.inst: CrashFunctionDescriptorExceptionTest.I<CrashFunctionDescriptorExceptionTest.B>) 4.5 +1 error