RFR: JDK-8203338: Unboxing in return from lambda miscompiled to throw ClassCastException
B. Blaser
bsrbnd at gmail.com
Sat Jun 16 22:20:21 UTC 2018
Hi,
As noted in the JBS issue, the following example fails at run-time with a CCE:
List.of('x', 'y').stream().max((a, b) -> { return List.of(a).get(0); });
The interesting point here is that removing 'return' makes it run successfully:
List.of('x', 'y').stream().max((a, b) -> List.of(a).get(0));
The problem seems to be in 'TransType.visitReturn()'. The lambda
method doesn't yet exist ('currentMethod == null', see
'TransType.visitLambda()') causing the return expression type to be
set to the erasure of 'List.get()' (= Object) which further causes the
type conversion problem (see
'LambdaToMethod.makeLambdaStatementBody()').
The suggested fix (here under) is to keep the original erased
expression type (= Character) if 'currentMethod == null'.
Tier1 is OK.
Any feedback is welcome,
Bernard
diff -r ed8de3d0cd28
src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TransTypes.java
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TransTypes.java
Sat Jun 16 10:10:54 2018 +0100
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TransTypes.java
Sat Jun 16 21:16:33 2018 +0200
@@ -601,7 +601,8 @@
}
public void visitReturn(JCReturn tree) {
- tree.expr = translate(tree.expr, currentMethod != null ?
types.erasure(currentMethod.type).getReturnType() : null);
+ tree.expr = translate(tree.expr, currentMethod != null ?
types.erasure(currentMethod.type).getReturnType() :
+ tree.expr != null ? types.erasure(tree.expr.type) : null);
result = tree;
}
More information about the compiler-dev
mailing list