JDK-6425594 : Warn about problematic forward references
  • Type: Enhancement
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 6
  • Priority: P4
  • Status: Open
  • Resolution: Unresolved
  • OS: generic
  • CPU: generic
  • Submitted: 2006-05-14
  • Updated: 2010-12-04
Related Reports
Relates :  
Description
The following program compiles:

class Test {
    static Object x = Test.x;
}
This is rejected by javac:

class Test {
    static Object x = x;
}

Since Test.x and x represent the same variable should the compiler
reject both programs?

Comments
SUGGESTED FIX Includes a fix for 6424491: Index: j2se/src/share/classes/com/sun/tools/javac/comp/Attr.java --- /tmp/geta5084 2006-05-15 00:26:23.343330144 -0700 +++ Attr.java 2006-05-14 13:44:46.000000000 -0700 @@ -1690,7 +1690,7 @@ // ..., evaluate its initializer, if it has one, and check for // illegal forward reference. - checkInit(tree, env, v); + checkInit(tree, env, v, false); // If symbol is a local variable accessed from an embedded // inner class check that it is final. @@ -1791,9 +1791,11 @@ // If that symbol is a variable, ... if (sym.kind == VAR) { - // ..., evaluate its initializer, if it has one VarSymbol v = (VarSymbol)sym; - v.getConstValue(); // ensure initializer is evaluated + + // ..., evaluate its initializer, if it has one, and check for + // illegal forward reference. + checkInit(tree, env, v, true); // If we are expecting a variable (as opposed to a value), check // that the variable is assignable in the current environment. @@ -2079,11 +2081,10 @@ * @param env The current environment. * @param v The variable's symbol. */ - private void checkInit(JCIdent tree, Env<AttrContext> env, VarSymbol v) { -// System.err.println(v + " " + ((v.flags() & STATIC) != 0) + " " + -// tree.pos + " " + v.pos + " " + -// Resolve.isStatic(env));//DEBUG - + private void checkInit(JCTree tree, + Env<AttrContext> env, + VarSymbol v, + boolean onlyWarning) { // 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 @@ -2097,8 +2098,14 @@ v.owner == env.info.scope.owner.enclClass() && ((v.flags() & STATIC) != 0) == Resolve.isStatic(env) && (env.tree.tag != JCTree.ASSIGN || - TreeInfo.skipParens(((JCAssign) env.tree).lhs) != tree)) + TreeInfo.skipParens(((JCAssign) env.tree).lhs) != tree)) { + if (onlyWarning && + !Flags.isEnum(v.owner) || !Flags.isStatic(v) || Flags.isConstant(v)) + // See issue 6425594 (javac accepts illegal forward references) + log.warning(tree.pos(), "forward.ref", v); + else log.error(tree.pos(), "illegal.forward.ref"); + } v.getConstValue(); // ensure initializer is evaluated @@ -2115,7 +2122,7 @@ * @param v The variable's symbol. * @see JLS 3rd Ed. (8.9 Enums) */ - private void checkEnumInitializer(JCIdent tree, Env<AttrContext> env, VarSymbol v) { + private void checkEnumInitializer(JCTree tree, Env<AttrContext> env, VarSymbol v) { // JLS 3rd Ed.: // // "It is a compile-time error to reference a static field
15-05-2006

EVALUATION The JLS is a bit unclear: http://java.sun.com/docs/books/jls/third_edition/html/classes.html#8.3.2.3 "The declaration of a member needs to appear textually before it is used only if the member is an instance (respectively static) field of a class or interface C and all of the following conditions hold: * The usage occurs in an instance (respectively static) variable initializer of C or in an instance (respectively static) initializer of C. * The usage is not on the left hand side of an assignment. * The usage is via a simple name. * C is the innermost class or interface enclosing the usage. A compile-time error occurs if any of the four requirements above are not met." The last sentence should be something like: "If the declaration of a member does not precede a use of that member, and the above conditions are met, a compile-time error occurs." So the program is valid since the third condition is not met. However, the compiler should be able to issue a warning and I have changed this issue to an RFE.
15-05-2006