8006684: Compiler produces java.lang.VerifyError: Bad type on operand stack

Tue, 22 Jan 2013 16:39:51 +0000

author
mcimadamore
date
Tue, 22 Jan 2013 16:39:51 +0000
changeset 1515
b61e5f801f7c
parent 1514
be443002e970
child 1516
8943b4213f59
child 1517
f5b70712e0d5

8006684: Compiler produces java.lang.VerifyError: Bad type on operand stack
Summary: Lambda desugaring generates spurious references to 'this' in static contexts
Reviewed-by: jjg

src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java file | annotate | diff | comparison | revisions
test/tools/javac/lambda/LambdaExpr21.java file | annotate | diff | comparison | revisions
     1.1 --- a/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java	Tue Jan 22 16:23:35 2013 +0000
     1.2 +++ b/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java	Tue Jan 22 16:39:51 2013 +0000
     1.3 @@ -859,8 +859,8 @@
     1.4              finally {
     1.5                  frameStack = prevStack;
     1.6              }
     1.7 -            if (frameStack.nonEmpty() && enclosingLambda() != null) {
     1.8 -                // Any class defined within a lambda is an implicit 'this' reference
     1.9 +            if (!tree.sym.isStatic() && frameStack.nonEmpty() && enclosingLambda() != null) {
    1.10 +                // Any (non-static) class defined within a lambda is an implicit 'this' reference
    1.11                  // because its constructor will reference the enclosing class
    1.12                  ((LambdaTranslationContext) context()).addSymbol(tree.sym.type.getEnclosingType().tsym, CAPTURED_THIS);
    1.13              }
    1.14 @@ -994,6 +994,11 @@
    1.15           * (required to skip synthetic lambda symbols)
    1.16           */
    1.17          private Symbol owner() {
    1.18 +            return owner(false);
    1.19 +        }
    1.20 +
    1.21 +        @SuppressWarnings("fallthrough")
    1.22 +        private Symbol owner(boolean skipLambda) {
    1.23              List<Frame> frameStack2 = frameStack;
    1.24              while (frameStack2.nonEmpty()) {
    1.25                  switch (frameStack2.head.tree.getTag()) {
    1.26 @@ -1012,7 +1017,8 @@
    1.27                      case METHODDEF:
    1.28                          return ((JCMethodDecl)frameStack2.head.tree).sym;
    1.29                      case LAMBDA:
    1.30 -                        return ((LambdaTranslationContext)contextMap.get(frameStack2.head.tree)).translatedSym;
    1.31 +                        if (!skipLambda)
    1.32 +                            return ((LambdaTranslationContext)contextMap.get(frameStack2.head.tree)).translatedSym;
    1.33                      default:
    1.34                          frameStack2 = frameStack2.tail;
    1.35                  }
    1.36 @@ -1311,8 +1317,9 @@
    1.37              }
    1.38  
    1.39              Type enclosingType() {
    1.40 -                //local inner classes defined inside a lambda are always non-static
    1.41 -                return owner.enclClass().type;
    1.42 +                return owner.isStatic() ?
    1.43 +                        Type.noType :
    1.44 +                        owner.enclClass().type;
    1.45              }
    1.46  
    1.47              Type generatedLambdaSig() {
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/test/tools/javac/lambda/LambdaExpr21.java	Tue Jan 22 16:39:51 2013 +0000
     2.3 @@ -0,0 +1,67 @@
     2.4 +/*
     2.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
     2.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     2.7 + *
     2.8 + * This code is free software; you can redistribute it and/or modify it
     2.9 + * under the terms of the GNU General Public License version 2 only, as
    2.10 + * published by the Free Software Foundation.
    2.11 + *
    2.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
    2.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    2.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    2.15 + * version 2 for more details (a copy is included in the LICENSE file that
    2.16 + * accompanied this code).
    2.17 + *
    2.18 + * You should have received a copy of the GNU General Public License version
    2.19 + * 2 along with this work; if not, write to the Free Software Foundation,
    2.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    2.21 + *
    2.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    2.23 + * or visit www.oracle.com if you need additional information or have any
    2.24 + * questions.
    2.25 + */
    2.26 +
    2.27 +/*
    2.28 + * @test
    2.29 + * @bug 8006684
    2.30 + * @summary Compiler produces java.lang.VerifyError: Bad type on operand stack
    2.31 + * @run main LambdaExpr21
    2.32 + */
    2.33 +public class LambdaExpr21 {
    2.34 +
    2.35 +    static int assertionCount = 0;
    2.36 +
    2.37 +    static void assertTrue(boolean cond) {
    2.38 +        assertionCount++;
    2.39 +        if (!cond)
    2.40 +            throw new AssertionError();
    2.41 +    }
    2.42 +
    2.43 +    interface SAM {
    2.44 +        void foo();
    2.45 +    }
    2.46 +
    2.47 +    static class Checker {
    2.48 +        Checker(boolean cond) {
    2.49 +            assertTrue(cond);
    2.50 +        }
    2.51 +    }
    2.52 +
    2.53 +    static {
    2.54 +        SAM s = ()-> { new Checker(true) { }; };
    2.55 +        s.foo();
    2.56 +    }
    2.57 +
    2.58 +    static void test(){
    2.59 +        SAM s = ()-> { new Checker(true) { }; };
    2.60 +        s.foo();
    2.61 +    }
    2.62 +
    2.63 +    static SAM s = ()-> { new Checker(true) { }; };
    2.64 +
    2.65 +    public static void main(String[] args) {
    2.66 +        test();
    2.67 +        s.foo();
    2.68 +        assertTrue(assertionCount == 3);
    2.69 +    }
    2.70 +}

mercurial