# HG changeset patch # User vromero # Date 1439255418 25200 # Node ID 48f213c9396541db2cae7c7ecb16429d71272b6e # Parent 53dca2b4b620633cc775fc586d6dee5b80901374 8053906: javac is accepting a self-referencing variable initializer inside a lambda expression Reviewed-by: jlahoda diff -r 53dca2b4b620 -r 48f213c93965 src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java Mon Aug 10 12:27:29 2015 -0700 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java Mon Aug 10 18:10:18 2015 -0700 @@ -3686,10 +3686,6 @@ Env env, VarSymbol v, boolean onlyWarning) { -// System.err.println(v + " " + ((v.flags() & STATIC) != 0) + " " + -// tree.pos + " " + v.pos + " " + -// Resolve.isStatic(env));//DEBUG - // A forward reference is diagnosed if the declaration position // of the variable is greater than the current tree position // and the tree and variable definition occur in the same class @@ -3697,14 +3693,15 @@ // This check applies only to class and instance // variables. Local variables follow different scope rules, // and are subject to definite assignment checking. - if ((env.info.enclVar == v || v.pos > tree.pos) && + Env initEnv = enclosingInitEnv(env); + if (initEnv != null && + (initEnv.info.enclVar == v || v.pos > tree.pos) && v.owner.kind == TYP && - enclosingInitEnv(env) != null && v.owner == env.info.scope.owner.enclClass() && ((v.flags() & STATIC) != 0) == Resolve.isStatic(env) && (!env.tree.hasTag(ASSIGN) || TreeInfo.skipParens(((JCAssign) env.tree).lhs) != tree)) { - String suffix = (env.info.enclVar == v) ? + String suffix = (initEnv.info.enclVar == v) ? "self.ref" : "forward.ref"; if (!onlyWarning || isStaticEnumField(v)) { log.error(tree.pos(), "illegal." + suffix); diff -r 53dca2b4b620 -r 48f213c93965 test/tools/javac/lambda/T8024809/SelfInitializerInLambdaTesta.java --- a/test/tools/javac/lambda/T8024809/SelfInitializerInLambdaTesta.java Mon Aug 10 12:27:29 2015 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,65 +0,0 @@ -/* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * @test - * @bug 8024809 - * @summary javac, some lambda programs are rejected by flow analysis - * @compile/fail/ref=SelfInitializerInLambdaTesta.out -XDrawDiagnostics SelfInitializerInLambdaTesta.java - */ - -public class SelfInitializerInLambdaTesta { - - final Runnable r1 = ()->System.out.println(r1); - - final Object lock = new Object(); - - final Runnable r2 = ()->{ - System.out.println(r2); - synchronized (lock){} - }; - - final Runnable r3 = ()->{ - synchronized (lock){ - System.out.println(r3); - } - }; - - final Runnable r4 = ()->{ - System.out.println(r4); - }; - - interface SAM { - int m(String s); - } - - final SAM s1 = (String s)->{ - System.out.println(s + s1.toString()); - return 0; - }; - - final SAM s2 = (s)->{ - System.out.println(s + s2.toString()); - return 0; - }; -} diff -r 53dca2b4b620 -r 48f213c93965 test/tools/javac/lambda/T8024809/SelfInitializerInLambdaTesta.out --- a/test/tools/javac/lambda/T8024809/SelfInitializerInLambdaTesta.out Mon Aug 10 12:27:29 2015 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,7 +0,0 @@ -SelfInitializerInLambdaTesta.java:33:48: compiler.err.illegal.self.ref -SelfInitializerInLambdaTesta.java:38:28: compiler.err.illegal.self.ref -SelfInitializerInLambdaTesta.java:44:32: compiler.err.illegal.self.ref -SelfInitializerInLambdaTesta.java:49:28: compiler.err.illegal.self.ref -SelfInitializerInLambdaTesta.java:57:32: compiler.err.illegal.self.ref -SelfInitializerInLambdaTesta.java:62:32: compiler.err.illegal.self.ref -6 errors diff -r 53dca2b4b620 -r 48f213c93965 test/tools/javac/lambda/T8024809/SelfInitializerInLambdaTestb.java --- a/test/tools/javac/lambda/T8024809/SelfInitializerInLambdaTestb.java Mon Aug 10 12:27:29 2015 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * @test - * @bug 8024809 - * @summary javac, some lambda programs are rejected by flow analysis - * @compile/fail/ref=SelfInitializerInLambdaTestb.out -XDrawDiagnostics SelfInitializerInLambdaTestb.java - */ - -public class SelfInitializerInLambdaTestb { - - final Runnable r1; - - final Runnable r2 = ()-> System.out.println(r1); - - SelfInitializerInLambdaTestb() { - r1 = ()->System.out.println(r1); - } -} diff -r 53dca2b4b620 -r 48f213c93965 test/tools/javac/lambda/T8024809/SelfInitializerInLambdaTestb.out --- a/test/tools/javac/lambda/T8024809/SelfInitializerInLambdaTestb.out Mon Aug 10 12:27:29 2015 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,3 +0,0 @@ -SelfInitializerInLambdaTestb.java:35:49: compiler.err.var.might.not.have.been.initialized: r1 -SelfInitializerInLambdaTestb.java:38:37: compiler.err.var.might.not.have.been.initialized: r1 -2 errors diff -r 53dca2b4b620 -r 48f213c93965 test/tools/javac/lambda/self_initializer/T8024809/SelfInitializerInLambdaTesta.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/lambda/self_initializer/T8024809/SelfInitializerInLambdaTesta.java Mon Aug 10 18:10:18 2015 -0700 @@ -0,0 +1,42 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8024809 + * @summary javac, some lambda programs are rejected by flow analysis + * @compile/fail/ref=SelfInitializerInLambdaTesta.out -XDrawDiagnostics SelfInitializerInLambdaTesta.java + */ + +public class SelfInitializerInLambdaTesta { + + final Runnable r1 = ()->System.out.println(r1); + + final Object lock = new Object(); + + final Runnable r2 = ()->{ + System.out.println(r2); + synchronized (lock){} + }; + + final Runnable r3 = ()->{ + synchronized (lock){ + System.out.println(r3); + } + }; + + final Runnable r4 = ()->{ + System.out.println(r4); + }; + + interface SAM { + int m(String s); + } + + final SAM s1 = (String s)->{ + System.out.println(s + s1.toString()); + return 0; + }; + + final SAM s2 = (s)->{ + System.out.println(s + s2.toString()); + return 0; + }; +} diff -r 53dca2b4b620 -r 48f213c93965 test/tools/javac/lambda/self_initializer/T8024809/SelfInitializerInLambdaTesta.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/lambda/self_initializer/T8024809/SelfInitializerInLambdaTesta.out Mon Aug 10 18:10:18 2015 -0700 @@ -0,0 +1,7 @@ +SelfInitializerInLambdaTesta.java:10:48: compiler.err.illegal.self.ref +SelfInitializerInLambdaTesta.java:15:28: compiler.err.illegal.self.ref +SelfInitializerInLambdaTesta.java:21:32: compiler.err.illegal.self.ref +SelfInitializerInLambdaTesta.java:26:28: compiler.err.illegal.self.ref +SelfInitializerInLambdaTesta.java:34:32: compiler.err.illegal.self.ref +SelfInitializerInLambdaTesta.java:39:32: compiler.err.illegal.self.ref +6 errors diff -r 53dca2b4b620 -r 48f213c93965 test/tools/javac/lambda/self_initializer/T8024809/SelfInitializerInLambdaTestb.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/lambda/self_initializer/T8024809/SelfInitializerInLambdaTestb.java Mon Aug 10 18:10:18 2015 -0700 @@ -0,0 +1,17 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8024809 + * @summary javac, some lambda programs are rejected by flow analysis + * @compile/fail/ref=SelfInitializerInLambdaTestb.out -XDrawDiagnostics SelfInitializerInLambdaTestb.java + */ + +public class SelfInitializerInLambdaTestb { + + final Runnable r1; + + final Runnable r2 = ()-> System.out.println(r1); + + SelfInitializerInLambdaTestb() { + r1 = ()->System.out.println(r1); + } +} diff -r 53dca2b4b620 -r 48f213c93965 test/tools/javac/lambda/self_initializer/T8024809/SelfInitializerInLambdaTestb.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/lambda/self_initializer/T8024809/SelfInitializerInLambdaTestb.out Mon Aug 10 18:10:18 2015 -0700 @@ -0,0 +1,3 @@ +SelfInitializerInLambdaTestb.java:12:49: compiler.err.var.might.not.have.been.initialized: r1 +SelfInitializerInLambdaTestb.java:15:37: compiler.err.var.might.not.have.been.initialized: r1 +2 errors diff -r 53dca2b4b620 -r 48f213c93965 test/tools/javac/lambda/self_initializer/T8053906/SelfInitializerInLambdaTestc.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/lambda/self_initializer/T8053906/SelfInitializerInLambdaTestc.java Mon Aug 10 18:10:18 2015 -0700 @@ -0,0 +1,26 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8053906 + * @summary javac, some lambda programs are rejected by flow analysis + * @compile/fail/ref=SelfInitializerInLambdaTestc.out -XDrawDiagnostics SelfInitializerInLambdaTestc.java + */ + +public class SelfInitializerInLambdaTestc { + interface SAM { + void foo(); + } + + final SAM notInitialized = ()-> { + SAM simpleVariable = () -> notInitialized.foo(); + }; + + final SAM notInitialized2 = ()-> { + SAM simpleVariable1 = () -> { + SAM simpleVariable2 = () -> { + SAM simpleVariable3 = () -> { + SAM simpleVariable4 = () -> notInitialized2.foo(); + }; + }; + }; + }; +} diff -r 53dca2b4b620 -r 48f213c93965 test/tools/javac/lambda/self_initializer/T8053906/SelfInitializerInLambdaTestc.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/lambda/self_initializer/T8053906/SelfInitializerInLambdaTestc.out Mon Aug 10 18:10:18 2015 -0700 @@ -0,0 +1,3 @@ +SelfInitializerInLambdaTestc.java:14:36: compiler.err.illegal.self.ref +SelfInitializerInLambdaTestc.java:21:49: compiler.err.illegal.self.ref +2 errors