Fri, 08 Aug 2008 17:43:24 +0100
6676362: Spurious forward reference error with final var + instance variable initializer
Summary: Some javac forward reference errors aren't compliant with the JLS
Reviewed-by: jjg
1.1 --- a/src/share/classes/com/sun/tools/javac/code/Symbol.java Fri Aug 08 17:38:20 2008 +0100 1.2 +++ b/src/share/classes/com/sun/tools/javac/code/Symbol.java Fri Aug 08 17:43:24 2008 +0100 1.3 @@ -923,14 +923,7 @@ 1.4 public Object call() { 1.5 JavaFileObject source = log.useSource(env.toplevel.sourcefile); 1.6 try { 1.7 - // In order to catch self-references, we set 1.8 - // the variable's declaration position to 1.9 - // maximal possible value, effectively marking 1.10 - // the variable as undefined. 1.11 - int pos = VarSymbol.this.pos; 1.12 - VarSymbol.this.pos = Position.MAXPOS; 1.13 Type itype = attr.attribExpr(initializer, env, type); 1.14 - VarSymbol.this.pos = pos; 1.15 if (itype.constValue() != null) 1.16 return attr.coerce(itype, type).constValue(); 1.17 else
2.1 --- a/src/share/classes/com/sun/tools/javac/comp/Attr.java Fri Aug 08 17:38:20 2008 +0100 2.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Attr.java Fri Aug 08 17:43:24 2008 +0100 2.3 @@ -730,9 +730,8 @@ 2.4 // In order to catch self-references, we set the variable's 2.5 // declaration position to maximal possible value, effectively 2.6 // marking the variable as undefined. 2.7 - v.pos = Position.MAXPOS; 2.8 + initEnv.info.enclVar = v; 2.9 attribExpr(tree.init, initEnv, v.type); 2.10 - v.pos = tree.pos; 2.11 } 2.12 } 2.13 result = tree.type = v.type; 2.14 @@ -2198,18 +2197,19 @@ 2.15 // This check applies only to class and instance 2.16 // variables. Local variables follow different scope rules, 2.17 // and are subject to definite assignment checking. 2.18 - if (v.pos > tree.pos && 2.19 + if ((env.info.enclVar == v || v.pos > tree.pos) && 2.20 v.owner.kind == TYP && 2.21 canOwnInitializer(env.info.scope.owner) && 2.22 v.owner == env.info.scope.owner.enclClass() && 2.23 ((v.flags() & STATIC) != 0) == Resolve.isStatic(env) && 2.24 (env.tree.getTag() != JCTree.ASSIGN || 2.25 TreeInfo.skipParens(((JCAssign) env.tree).lhs) != tree)) { 2.26 - 2.27 + String suffix = (env.info.enclVar == v) ? 2.28 + "self.ref" : "forward.ref"; 2.29 if (!onlyWarning || isStaticEnumField(v)) { 2.30 - log.error(tree.pos(), "illegal.forward.ref"); 2.31 + log.error(tree.pos(), "illegal." + suffix); 2.32 } else if (useBeforeDeclarationWarning) { 2.33 - log.warning(tree.pos(), "forward.ref", v); 2.34 + log.warning(tree.pos(), suffix, v); 2.35 } 2.36 } 2.37
3.1 --- a/src/share/classes/com/sun/tools/javac/comp/AttrContext.java Fri Aug 08 17:38:20 2008 +0100 3.2 +++ b/src/share/classes/com/sun/tools/javac/comp/AttrContext.java Fri Aug 08 17:43:24 2008 +0100 3.3 @@ -66,6 +66,11 @@ 3.4 */ 3.5 Lint lint; 3.6 3.7 + /** The variable whose initializer is being attributed 3.8 + * useful for detecting self-references in variable initializers 3.9 + */ 3.10 + Symbol enclVar = null; 3.11 + 3.12 /** Duplicate this context, replacing scope field and copying all others. 3.13 */ 3.14 AttrContext dup(Scope scope) { 3.15 @@ -77,6 +82,7 @@ 3.16 info.varArgs = varArgs; 3.17 info.tvars = tvars; 3.18 info.lint = lint; 3.19 + info.enclVar = enclVar; 3.20 return info; 3.21 } 3.22
4.1 --- a/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java Fri Aug 08 17:38:20 2008 +0100 4.2 +++ b/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java Fri Aug 08 17:43:24 2008 +0100 4.3 @@ -627,8 +627,11 @@ 4.4 tree.sym = v; 4.5 if (tree.init != null) { 4.6 v.flags_field |= HASINIT; 4.7 - if ((v.flags_field & FINAL) != 0 && tree.init.getTag() != JCTree.NEWCLASS) 4.8 - v.setLazyConstValue(initEnv(tree, env), log, attr, tree.init); 4.9 + if ((v.flags_field & FINAL) != 0 && tree.init.getTag() != JCTree.NEWCLASS) { 4.10 + Env<AttrContext> initEnv = getInitEnv(tree, env); 4.11 + initEnv.info.enclVar = v; 4.12 + v.setLazyConstValue(initEnv(tree, initEnv), log, attr, tree.init); 4.13 + } 4.14 } 4.15 if (chk.checkUnique(tree.pos(), v, enclScope)) { 4.16 chk.checkTransparentVar(tree.pos(), v, enclScope);
5.1 --- a/src/share/classes/com/sun/tools/javac/resources/compiler.properties Fri Aug 08 17:38:20 2008 +0100 5.2 +++ b/src/share/classes/com/sun/tools/javac/resources/compiler.properties Fri Aug 08 17:43:24 2008 +0100 5.3 @@ -200,6 +200,10 @@ 5.4 illegal forward reference 5.5 compiler.warn.forward.ref=\ 5.6 reference to variable ''{0}'' before it has been initialized 5.7 +compiler.err.illegal.self.ref=\ 5.8 + self-reference in initializer 5.9 +compiler.warn.self.ref=\ 5.10 + self-reference in initializer of variable ''{0}'' 5.11 compiler.err.illegal.generic.type.for.instof=\ 5.12 illegal generic type for instanceof 5.13 compiler.err.illegal.initializer.for.type=\
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 6.2 +++ b/test/tools/javac/ForwardReference/T6676362a.java Fri Aug 08 17:43:24 2008 +0100 6.3 @@ -0,0 +1,36 @@ 6.4 +/* 6.5 + * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved. 6.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 6.7 + * 6.8 + * This code is free software; you can redistribute it and/or modify it 6.9 + * under the terms of the GNU General Public License version 2 only, as 6.10 + * published by the Free Software Foundation. 6.11 + * 6.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 6.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 6.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 6.15 + * version 2 for more details (a copy is included in the LICENSE file that 6.16 + * accompanied this code). 6.17 + * 6.18 + * You should have received a copy of the GNU General Public License version 6.19 + * 2 along with this work; if not, write to the Free Software Foundation, 6.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 6.21 + * 6.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 6.23 + * CA 95054 USA or visit www.sun.com if you need additional information or 6.24 + * have any questions. 6.25 + */ 6.26 + 6.27 +/* 6.28 + * @test 6.29 + * @bug 6676362 6.30 + * @summary Spurious forward reference error with final var + instance variable initializer 6.31 + * @author Maurizio Cimadamore 6.32 + * 6.33 + * @compile T6676362a.java 6.34 + */ 6.35 + 6.36 +public class T6676362a { 6.37 + Object o = new Object() {Object m() {return o2;}}; 6.38 + final Object o2 = o; 6.39 +}
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 7.2 +++ b/test/tools/javac/ForwardReference/T6676362b.java Fri Aug 08 17:43:24 2008 +0100 7.3 @@ -0,0 +1,36 @@ 7.4 +/* 7.5 + * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved. 7.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 7.7 + * 7.8 + * This code is free software; you can redistribute it and/or modify it 7.9 + * under the terms of the GNU General Public License version 2 only, as 7.10 + * published by the Free Software Foundation. 7.11 + * 7.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 7.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 7.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 7.15 + * version 2 for more details (a copy is included in the LICENSE file that 7.16 + * accompanied this code). 7.17 + * 7.18 + * You should have received a copy of the GNU General Public License version 7.19 + * 2 along with this work; if not, write to the Free Software Foundation, 7.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 7.21 + * 7.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 7.23 + * CA 95054 USA or visit www.sun.com if you need additional information or 7.24 + * have any questions. 7.25 + */ 7.26 + 7.27 +/* 7.28 + * @test 7.29 + * @bug 6676362 7.30 + * @summary Spurious forward reference error with final var + instance variable initializer 7.31 + * @author Maurizio Cimadamore 7.32 + * 7.33 + * @compile T6676362b.java 7.34 + */ 7.35 + 7.36 +public class T6676362b { 7.37 + static final int i1 = T6676362b.i2; //legal - usage is not via simple name 7.38 + static final int i2 = i1; 7.39 +}
8.1 --- a/test/tools/javac/enum/forwardRef/T6425594.out Fri Aug 08 17:38:20 2008 +0100 8.2 +++ b/test/tools/javac/enum/forwardRef/T6425594.out Fri Aug 08 17:43:24 2008 +0100 8.3 @@ -1,4 +1,4 @@ 8.4 -T6425594.java:10:28: compiler.warn.forward.ref: x 8.5 +T6425594.java:10:28: compiler.warn.self.ref: x 8.6 T6425594.java:11:26: compiler.err.illegal.forward.ref 8.7 1 error 8.8 1 warning