Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 19 additions & 11 deletions src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java
Original file line number Diff line number Diff line change
Expand Up @@ -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());
}
}
Expand All @@ -1282,11 +1283,13 @@ enum PrologueVisitorMode {
class CtorPrologueVisitor extends TreeScanner {
Env<AttrContext> localEnv;
PrologueVisitorMode mode;
boolean isInitializer;

CtorPrologueVisitor(Env<AttrContext> localEnv, PrologueVisitorMode mode) {
CtorPrologueVisitor(Env<AttrContext> localEnv, PrologueVisitorMode mode, boolean isInitializer) {
this.localEnv = localEnv;
currentClassSym = localEnv.enclClass.sym;
this.mode = mode;
this.isInitializer = isInitializer;
}

boolean insideLambdaOrClassDef = false;
Expand Down Expand Up @@ -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))
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

reportPrologueError(tree, sym);
// we will need to generate a proxy for this field later on
if (!isInLHS) {
Expand Down Expand Up @@ -1642,13 +1649,13 @@ public void visitVarDef(JCVariableDecl tree) {
chk.checkDeprecatedAnnotation(tree.pos(), v);

if (tree.init != null) {
Env<AttrContext> 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<AttrContext> 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
Expand All @@ -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);
}
Expand Down
5 changes: 5 additions & 0 deletions test/langtools/tools/javac/SuperInit/EarlyAssignments.java
Original file line number Diff line number Diff line change
Expand Up @@ -180,4 +180,9 @@ public static class Inner9 {
super();
}
}

public static class Inner10 {
int x = 1;
int y = x + 1; // no warning expected here
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@
*/
import java.util.function.Function;
abstract value class AR<V> implements java.io.Serializable {
int b = 5;
public AR(V initialValue) {
}

public AR() {
}
}
Expand Down Expand Up @@ -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;
}
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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