mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-17 01:24:33 +02:00
8053906: javac is accepting a self-referencing variable initializer inside a lambda expression
Reviewed-by: jlahoda
This commit is contained in:
parent
966fc670ee
commit
8a2078e8a3
11 changed files with 102 additions and 122 deletions
|
@ -3686,10 +3686,6 @@ public class Attr extends JCTree.Visitor {
|
||||||
Env<AttrContext> env,
|
Env<AttrContext> env,
|
||||||
VarSymbol v,
|
VarSymbol v,
|
||||||
boolean onlyWarning) {
|
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
|
// A forward reference is diagnosed if the declaration position
|
||||||
// of the variable is greater than the current tree position
|
// of the variable is greater than the current tree position
|
||||||
// and the tree and variable definition occur in the same class
|
// and the tree and variable definition occur in the same class
|
||||||
|
@ -3697,14 +3693,15 @@ public class Attr extends JCTree.Visitor {
|
||||||
// This check applies only to class and instance
|
// This check applies only to class and instance
|
||||||
// variables. Local variables follow different scope rules,
|
// variables. Local variables follow different scope rules,
|
||||||
// and are subject to definite assignment checking.
|
// and are subject to definite assignment checking.
|
||||||
if ((env.info.enclVar == v || v.pos > tree.pos) &&
|
Env<AttrContext> initEnv = enclosingInitEnv(env);
|
||||||
|
if (initEnv != null &&
|
||||||
|
(initEnv.info.enclVar == v || v.pos > tree.pos) &&
|
||||||
v.owner.kind == TYP &&
|
v.owner.kind == TYP &&
|
||||||
enclosingInitEnv(env) != null &&
|
|
||||||
v.owner == env.info.scope.owner.enclClass() &&
|
v.owner == env.info.scope.owner.enclClass() &&
|
||||||
((v.flags() & STATIC) != 0) == Resolve.isStatic(env) &&
|
((v.flags() & STATIC) != 0) == Resolve.isStatic(env) &&
|
||||||
(!env.tree.hasTag(ASSIGN) ||
|
(!env.tree.hasTag(ASSIGN) ||
|
||||||
TreeInfo.skipParens(((JCAssign) env.tree).lhs) != tree)) {
|
TreeInfo.skipParens(((JCAssign) env.tree).lhs) != tree)) {
|
||||||
String suffix = (env.info.enclVar == v) ?
|
String suffix = (initEnv.info.enclVar == v) ?
|
||||||
"self.ref" : "forward.ref";
|
"self.ref" : "forward.ref";
|
||||||
if (!onlyWarning || isStaticEnumField(v)) {
|
if (!onlyWarning || isStaticEnumField(v)) {
|
||||||
log.error(tree.pos(), "illegal." + suffix);
|
log.error(tree.pos(), "illegal." + suffix);
|
||||||
|
|
|
@ -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;
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -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
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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
|
|
|
@ -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;
|
||||||
|
};
|
||||||
|
}
|
|
@ -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
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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
|
|
@ -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();
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
SelfInitializerInLambdaTestc.java:14:36: compiler.err.illegal.self.ref
|
||||||
|
SelfInitializerInLambdaTestc.java:21:49: compiler.err.illegal.self.ref
|
||||||
|
2 errors
|
Loading…
Add table
Add a link
Reference in a new issue