RFR: JDK-8184989. Incorrect class file created when passing lambda in inner class constructor and outer is subclass
B. Blaser
bsrbnd at gmail.com
Wed Aug 2 13:02:59 UTC 2017
Andrey, Srikanth, All,
At first sight, this looks good to me.
I would perhaps rewrite it as here under, to be more expressive.
I did it rapidly on a quite old jdk9 revision (sorry...), but this
should work on the latest, too.
What do you think of this rewriting?
Regards,
Bernard
diff -r 43a83431f19d
src/jdk.compiler/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java
Wed Mar 15 15:46:43 2017 +0100
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java
Wed Aug 02 14:11:08 2017 +0200
@@ -2103,15 +2103,23 @@
}
break;
case CAPTURED_OUTER_THIS:
- if (lambdaIdent.sym.owner.kind == TYP &&
m.containsKey(lambdaIdent.sym.owner)) {
- // Transform outer instance variable
references anchoring them to the captured synthetic.
- Symbol tSym = m.get(lambdaIdent.sym.owner);
- JCExpression t =
make.Ident(tSym).setType(lambdaIdent.sym.owner.type);
-
tSym.setTypeAttributes(lambdaIdent.sym.owner.getRawTypeAttributes());
- t = make.Select(t, lambdaIdent.name);
- t.setType(lambdaIdent.type);
- TreeInfo.setSymbol(t, lambdaIdent.sym);
- return t;
+ if (lambdaIdent.sym.owner.kind == TYP) {
+ for (Symbol out: m.keySet()) {
+ for (Type type = out.type;
+ type.hasTag(CLASS) &&
!type.isErroneous();
+
type=((ClassSymbol)type.tsym).getSuperclass()) {
+ if
(type.tsym.equals(lambdaIdent.sym.owner)) {
+ // Transform outer
instance variable references anchoring them to the captured synthetic.
+ Symbol tSym = m.get(out);
+ JCExpression t =
make.Ident(tSym).setType(lambdaIdent.sym.owner.type);
+
tSym.setTypeAttributes(lambdaIdent.sym.owner.getRawTypeAttributes());
+ t = make.Select(t,
lambdaIdent.name);
+ t.setType(lambdaIdent.type);
+ TreeInfo.setSymbol(t,
lambdaIdent.sym);
+ return t;
+ }
+ }
+ }
}
break;
}
On 1 August 2017 at 14:15, Srikanth <srikanth.adayapalam at oracle.com> wrote:
>
> Thanks Andrey.
>
> I'll take a look in the coming week and let you know of any feedback.
>
> Srikanth
>
>
> On Monday 31 July 2017 08:00 PM, Andrey Petushkov wrote:
>
> Dear Compiler Team,
>
> We’ve occasionally found out that there is a problem in javac related to
> lambda support, in part related to referencing the outer’s entity which
> otherwise would be captured by using inner this, but cannot be since it’s
> not yet fully initialized. More specifically this seem to be omission in the
> fix for JDK-8129740:
> it's fix works fine if it deals with the entity from the outer class(es),
> but fails if the entity is inherited from outer’s parent. Consider the
> following source code:
>
> A.java
> public class A {
> public boolean test(){
> return true;
> }
> class AA{
> public AA(Condition condition) {
> }
> }
> }
>
> Condition.java
> public interface Condition<T> {
> boolean check(T t);
> }
>
> B.java
> public class B extends A {
> private final BA myBA;
> public B() {
> myBA = new BA();
> }
> public class BA extends AA{
> public BA() {
> super(o -> test());
> }
> }
> public static void main(String[] args) {
> B b = new B();
> System.out.println(b);
> }
> }
>
>
> source compiles but execution of B fails with:
> Exception in thread "main" java.lang.VerifyError: Bad type on operand stack
> Exception Details:
> Location:
> B$BA.lambda$new$0(LB;Ljava/lang/Object;)Z @1: getfield
> Reason:
> Type 'B' (current frame, stack[0]) is not assignable to 'B$BA'
> Current Frame:
> bci: @1
> flags: { }
> locals: { 'B', 'java/lang/Object' }
> stack: { 'B' }
> Bytecode:
> 0x0000000: 2ab4 0001 b600 04ac
>
> at B.<init>(B.java:6)
> at B.main(B.java:17)
>
> The problem is reproduced on both latest 8u and 9 (by the time of the bug
> submission)
>
> My naive attempt to fix could be seen here
> http://cr.openjdk.java.net/~apetushkov/8184989/webrev/ (based on latest 8u)
> Please could you consider reviewing/improving it or suggesting improvement
> direction as appropriate
>
> Thanks,
> Andrey
>
>
More information about the compiler-dev
mailing list