Skip to content

Commit b1d14c6

Browse files
author
Vicente Romero
committed
8371382: [lworld] Javac accepts field initializer that refers to a superclass field
Reviewed-by: liach
1 parent 58d748e commit b1d14c6

File tree

4 files changed

+32
-13
lines changed

4 files changed

+32
-13
lines changed

src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1258,7 +1258,8 @@ public void visitMethodDef(JCMethodDecl tree) {
12581258
PrologueVisitorMode.WARNINGS_ONLY :
12591259
thisInvocation ?
12601260
PrologueVisitorMode.THIS_CONSTRUCTOR :
1261-
PrologueVisitorMode.SUPER_CONSTRUCTOR);
1261+
PrologueVisitorMode.SUPER_CONSTRUCTOR,
1262+
false);
12621263
ctorPrologueVisitor.scan(prologueCode.toList());
12631264
}
12641265
}
@@ -1282,11 +1283,13 @@ enum PrologueVisitorMode {
12821283
class CtorPrologueVisitor extends TreeScanner {
12831284
Env<AttrContext> localEnv;
12841285
PrologueVisitorMode mode;
1286+
boolean isInitializer;
12851287

1286-
CtorPrologueVisitor(Env<AttrContext> localEnv, PrologueVisitorMode mode) {
1288+
CtorPrologueVisitor(Env<AttrContext> localEnv, PrologueVisitorMode mode, boolean isInitializer) {
12871289
this.localEnv = localEnv;
12881290
currentClassSym = localEnv.enclClass.sym;
12891291
this.mode = mode;
1292+
this.isInitializer = isInitializer;
12901293
}
12911294

12921295
boolean insideLambdaOrClassDef = false;
@@ -1512,10 +1515,14 @@ void analyzeSymbol(JCTree tree) {
15121515
} else if (isEarlyReference(localEnv, tree, sym)) {
15131516
/* now this is a `proper` instance field of the current class
15141517
* references to fields of identity classes which happen to have initializers are
1515-
* not allowed in the prologue
1518+
* not allowed in the prologue.
1519+
* But it is OK for a field with initializer to refer to another field with initializer,
1520+
* so no warning or error if we are analyzing a field initializer.
15161521
*/
15171522
if (insideLambdaOrClassDef ||
1518-
(!localEnv.enclClass.sym.isValueClass() && (sym.flags_field & HASINIT) != 0))
1523+
(!localEnv.enclClass.sym.isValueClass() &&
1524+
(sym.flags_field & HASINIT) != 0 &&
1525+
!isInitializer))
15191526
reportPrologueError(tree, sym);
15201527
// we will need to generate a proxy for this field later on
15211528
if (!isInLHS) {
@@ -1642,13 +1649,13 @@ public void visitVarDef(JCVariableDecl tree) {
16421649
chk.checkDeprecatedAnnotation(tree.pos(), v);
16431650

16441651
if (tree.init != null) {
1652+
Env<AttrContext> initEnv = memberEnter.initEnv(tree, env);
16451653
if ((v.flags_field & FINAL) == 0 ||
16461654
!memberEnter.needsLazyConstValue(tree.init)) {
16471655
// Not a compile-time constant
16481656
// Attribute initializer in a new environment
16491657
// with the declared variable as owner.
16501658
// Check that initializer conforms to variable's declared type.
1651-
Env<AttrContext> initEnv = memberEnter.initEnv(tree, env);
16521659
initEnv.info.lint = lint;
16531660
// In order to catch self-references, we set the variable's
16541661
// declaration position to maximal possible value, effectively
@@ -1665,16 +1672,17 @@ public void visitVarDef(JCVariableDecl tree) {
16651672
//fixup local variable type
16661673
v.type = chk.checkLocalVarType(tree, tree.init.type, tree.name);
16671674
}
1668-
if (allowValueClasses && v.owner.kind == TYP && !v.isStatic()) {
1669-
// strict field initializers are inlined in constructor's prologues
1670-
CtorPrologueVisitor ctorPrologueVisitor = new CtorPrologueVisitor(initEnv,
1671-
!v.isStrict() ? PrologueVisitorMode.WARNINGS_ONLY : PrologueVisitorMode.SUPER_CONSTRUCTOR);
1672-
ctorPrologueVisitor.scan(tree.init);
1673-
}
16741675
} finally {
16751676
initEnv.info.ctorPrologue = previousCtorPrologue;
16761677
}
16771678
}
1679+
if (allowValueClasses && v.owner.kind == TYP && !v.isStatic()) {
1680+
// strict field initializers are inlined in constructor's prologues
1681+
CtorPrologueVisitor ctorPrologueVisitor = new CtorPrologueVisitor(initEnv,
1682+
!v.isStrict() ? PrologueVisitorMode.WARNINGS_ONLY : PrologueVisitorMode.SUPER_CONSTRUCTOR,
1683+
true);
1684+
ctorPrologueVisitor.scan(tree.init);
1685+
}
16781686
if (tree.isImplicitlyTyped()) {
16791687
setSyntheticVariableType(tree, v.type);
16801688
}

test/langtools/tools/javac/SuperInit/EarlyAssignments.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,4 +180,9 @@ public static class Inner9 {
180180
super();
181181
}
182182
}
183+
184+
public static class Inner10 {
185+
int x = 1;
186+
int y = x + 1; // no warning expected here
187+
}
183188
}

test/langtools/tools/javac/SuperInit/ValueClassSuperInitFails.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@
77
*/
88
import java.util.function.Function;
99
abstract value class AR<V> implements java.io.Serializable {
10+
int b = 5;
1011
public AR(V initialValue) {
1112
}
12-
1313
public AR() {
1414
}
1515
}
@@ -178,4 +178,8 @@ public ValueClassSuperInitFails(int[][] z) {
178178
public ValueClassSuperInitFails(long[][] z) {
179179
super(new Inner1()); // this should FAIL
180180
}
181+
182+
// these two should FAIL
183+
int a = b;
184+
int aa = super.b;
181185
}

test/langtools/tools/javac/SuperInit/ValueClassSuperInitFails.out

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ ValueClassSuperInitFails.java:148:9: compiler.err.non.canonical.constructor.invo
1414
ValueClassSuperInitFails.java:161:46: compiler.err.cant.ref.before.ctor.called: hashCode()
1515
ValueClassSuperInitFails.java:175:49: compiler.err.cant.ref.before.ctor.called: x
1616
ValueClassSuperInitFails.java:179:15: compiler.err.cant.ref.before.ctor.called: ValueClassSuperInitFails
17+
ValueClassSuperInitFails.java:183:13: compiler.err.cant.ref.before.ctor.called: b
18+
ValueClassSuperInitFails.java:184:19: compiler.err.cant.ref.before.ctor.called: b
1719
ValueClassSuperInitFails.java:43:13: compiler.err.call.must.only.appear.in.ctor
1820
ValueClassSuperInitFails.java:47:14: compiler.err.call.must.only.appear.in.ctor
1921
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
2527
ValueClassSuperInitFails.java:170:18: compiler.err.call.must.only.appear.in.ctor
2628
- compiler.note.preview.filename: ValueClassSuperInitFails.java, DEFAULT
2729
- compiler.note.preview.recompile
28-
25 errors
30+
27 errors

0 commit comments

Comments
 (0)