diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java index 4840750a40d..fdb9753c14f 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java @@ -1258,7 +1258,8 @@ public void visitMethodDef(JCMethodDecl tree) { PrologueVisitorMode.WARNINGS_ONLY : thisInvocation ? PrologueVisitorMode.THIS_CONSTRUCTOR : - PrologueVisitorMode.SUPER_CONSTRUCTOR); + PrologueVisitorMode.SUPER_CONSTRUCTOR, + false); ctorPrologueVisitor.scan(prologueCode.toList()); } } @@ -1282,11 +1283,13 @@ enum PrologueVisitorMode { class CtorPrologueVisitor extends TreeScanner { Env localEnv; PrologueVisitorMode mode; + boolean isInitializer; - CtorPrologueVisitor(Env localEnv, PrologueVisitorMode mode) { + CtorPrologueVisitor(Env localEnv, PrologueVisitorMode mode, boolean isInitializer) { this.localEnv = localEnv; currentClassSym = localEnv.enclClass.sym; this.mode = mode; + this.isInitializer = isInitializer; } boolean insideLambdaOrClassDef = false; @@ -1512,10 +1515,14 @@ void analyzeSymbol(JCTree tree) { } else if (isEarlyReference(localEnv, tree, sym)) { /* now this is a `proper` instance field of the current class * references to fields of identity classes which happen to have initializers are - * not allowed in the prologue + * not allowed in the prologue. + * But it is OK for a field with initializer to refer to another field with initializer, + * so no warning or error if we are analyzing a field initializer. */ if (insideLambdaOrClassDef || - (!localEnv.enclClass.sym.isValueClass() && (sym.flags_field & HASINIT) != 0)) + (!localEnv.enclClass.sym.isValueClass() && + (sym.flags_field & HASINIT) != 0 && + !isInitializer)) reportPrologueError(tree, sym); // we will need to generate a proxy for this field later on if (!isInLHS) { @@ -1642,13 +1649,13 @@ public void visitVarDef(JCVariableDecl tree) { chk.checkDeprecatedAnnotation(tree.pos(), v); if (tree.init != null) { + Env initEnv = memberEnter.initEnv(tree, env); if ((v.flags_field & FINAL) == 0 || !memberEnter.needsLazyConstValue(tree.init)) { // Not a compile-time constant // Attribute initializer in a new environment // with the declared variable as owner. // Check that initializer conforms to variable's declared type. - Env initEnv = memberEnter.initEnv(tree, env); initEnv.info.lint = lint; // In order to catch self-references, we set the variable's // declaration position to maximal possible value, effectively @@ -1665,16 +1672,17 @@ public void visitVarDef(JCVariableDecl tree) { //fixup local variable type v.type = chk.checkLocalVarType(tree, tree.init.type, tree.name); } - if (allowValueClasses && v.owner.kind == TYP && !v.isStatic()) { - // strict field initializers are inlined in constructor's prologues - CtorPrologueVisitor ctorPrologueVisitor = new CtorPrologueVisitor(initEnv, - !v.isStrict() ? PrologueVisitorMode.WARNINGS_ONLY : PrologueVisitorMode.SUPER_CONSTRUCTOR); - ctorPrologueVisitor.scan(tree.init); - } } finally { initEnv.info.ctorPrologue = previousCtorPrologue; } } + if (allowValueClasses && v.owner.kind == TYP && !v.isStatic()) { + // strict field initializers are inlined in constructor's prologues + CtorPrologueVisitor ctorPrologueVisitor = new CtorPrologueVisitor(initEnv, + !v.isStrict() ? PrologueVisitorMode.WARNINGS_ONLY : PrologueVisitorMode.SUPER_CONSTRUCTOR, + true); + ctorPrologueVisitor.scan(tree.init); + } if (tree.isImplicitlyTyped()) { setSyntheticVariableType(tree, v.type); } diff --git a/test/langtools/tools/javac/SuperInit/EarlyAssignments.java b/test/langtools/tools/javac/SuperInit/EarlyAssignments.java index fdc9eb27d60..07ebf888a79 100644 --- a/test/langtools/tools/javac/SuperInit/EarlyAssignments.java +++ b/test/langtools/tools/javac/SuperInit/EarlyAssignments.java @@ -180,4 +180,9 @@ public static class Inner9 { super(); } } + + public static class Inner10 { + int x = 1; + int y = x + 1; // no warning expected here + } } diff --git a/test/langtools/tools/javac/SuperInit/ValueClassSuperInitFails.java b/test/langtools/tools/javac/SuperInit/ValueClassSuperInitFails.java index 6c4a1de0818..e896aa97791 100644 --- a/test/langtools/tools/javac/SuperInit/ValueClassSuperInitFails.java +++ b/test/langtools/tools/javac/SuperInit/ValueClassSuperInitFails.java @@ -7,9 +7,9 @@ */ import java.util.function.Function; abstract value class AR implements java.io.Serializable { + int b = 5; public AR(V initialValue) { } - public AR() { } } @@ -178,4 +178,8 @@ public ValueClassSuperInitFails(int[][] z) { public ValueClassSuperInitFails(long[][] z) { super(new Inner1()); // this should FAIL } + + // these two should FAIL + int a = b; + int aa = super.b; } diff --git a/test/langtools/tools/javac/SuperInit/ValueClassSuperInitFails.out b/test/langtools/tools/javac/SuperInit/ValueClassSuperInitFails.out index 9ce5ced7c4d..8698f62a505 100644 --- a/test/langtools/tools/javac/SuperInit/ValueClassSuperInitFails.out +++ b/test/langtools/tools/javac/SuperInit/ValueClassSuperInitFails.out @@ -14,6 +14,8 @@ ValueClassSuperInitFails.java:148:9: compiler.err.non.canonical.constructor.invo ValueClassSuperInitFails.java:161:46: compiler.err.cant.ref.before.ctor.called: hashCode() ValueClassSuperInitFails.java:175:49: compiler.err.cant.ref.before.ctor.called: x ValueClassSuperInitFails.java:179:15: compiler.err.cant.ref.before.ctor.called: ValueClassSuperInitFails +ValueClassSuperInitFails.java:183:13: compiler.err.cant.ref.before.ctor.called: b +ValueClassSuperInitFails.java:184:19: compiler.err.cant.ref.before.ctor.called: b ValueClassSuperInitFails.java:43:13: compiler.err.call.must.only.appear.in.ctor ValueClassSuperInitFails.java:47:14: compiler.err.call.must.only.appear.in.ctor ValueClassSuperInitFails.java:51:14: compiler.err.call.must.only.appear.in.ctor @@ -25,4 +27,4 @@ ValueClassSuperInitFails.java:99:13: compiler.err.return.before.superclass.initi ValueClassSuperInitFails.java:170:18: compiler.err.call.must.only.appear.in.ctor - compiler.note.preview.filename: ValueClassSuperInitFails.java, DEFAULT - compiler.note.preview.recompile -25 errors +27 errors