From 338f5d8fbc9bfd1a94fb5598f2169c92195b72cb Mon Sep 17 00:00:00 2001 From: Vicente Romero Date: Tue, 22 Jul 2025 17:47:41 -0400 Subject: [PATCH 01/10] removing all checks from Resolve --- .../com/sun/tools/javac/comp/Attr.java | 178 +++++++++++++++++- .../com/sun/tools/javac/comp/Resolve.java | 84 +-------- .../com/sun/tools/javac/tree/TreeInfo.java | 27 +++ .../maskSyntheticModifier/Foo.class | Bin 667 -> 0 bytes test/jdk/java/lang/Class/EnumPoseur.class | Bin 256 -> 0 bytes .../java/lang/Class/forName/classes/0.class | Bin 408 -> 0 bytes .../java/lang/Class/forName/classes/3.class | Bin 408 -> 0 bytes .../java/lang/Class/forName/classes/Z.class | Bin 408 -> 0 bytes .../lang/Class/forName/classes/comma.class | Bin 408 -> 0 bytes .../lang/Class/forName/classes/hyphen.class | Bin 408 -> 0 bytes .../Class/forName/classes/left-square.class | Bin 408 -> 0 bytes .../lang/Class/forName/classes/period.class | Bin 408 -> 0 bytes .../lang/Class/forName/classes/plus.class | Bin 408 -> 0 bytes .../Class/forName/classes/right-square.class | Bin 408 -> 0 bytes .../Class/forName/classes/semicolon.class | Bin 408 -> 0 bytes test/jdk/sun/misc/Hello.class | Bin 401 -> 0 bytes .../security/tools/jarsigner/oldsig/A.class | Bin 176 -> 0 bytes .../javac/SuperInit/EarlyAssignments.out | 15 +- .../tools/javac/SuperInit/SuperInitFails.out | 11 +- 19 files changed, 220 insertions(+), 95 deletions(-) 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 cc0e5c38e58..8517b19bf78 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 @@ -327,7 +327,7 @@ void checkAssignable(DiagnosticPosition pos, VarSymbol v, JCTree base, Env localEnv; + boolean ctorPrologue = true; + + CtorPrologueVisitor(Env localEnv) { + this.localEnv = localEnv; + } + + @Override + public void visitApply(JCMethodInvocation tree) { + super.visitApply(tree); + Name name = TreeInfo.name(tree.meth); + boolean isConstructorCall = name == names._this || name == names._super; + if (ctorPrologue) { + Symbol msym = TreeInfo.symbolFor(tree.meth); + if (!isConstructorCall && !msym.isStatic()) { + if (msym.owner == env.enclClass.sym) { + // instance method? + if (tree.meth instanceof JCFieldAccess fa) { + if (TreeInfo.isExplicitThisReference(types, (ClassType)env.enclClass.sym.type, fa.selected)) { + log.error(tree.meth, Errors.CantRefBeforeCtorCalled(msym)); + } + } else { + log.error(tree.meth, Errors.CantRefBeforeCtorCalled(msym)); + } + } else if (msym.isMemberOf(env.enclClass.sym, types)){ + // where we are dealing with an inherited method, probably an error too + if (tree.meth instanceof JCFieldAccess fa) { + if (TreeInfo.isExplicitThisReference(types, (ClassType)env.enclClass.sym.type, fa.selected)) { + log.error(tree.meth, Errors.CantRefBeforeCtorCalled(msym)); + } + } else { + log.error(tree.meth, Errors.CantRefBeforeCtorCalled(msym)); + } + } + } + // we still need to check the args + for (JCExpression arg : tree.args) { + analyzeTree(arg); + } + } + if (isConstructorCall) { + ctorPrologue = false; + } + } + + @Override + public void visitNewClass(JCNewClass tree) { + super.visitNewClass(tree); + if (ctorPrologue) { + if (tree.type.tsym.isEnclosedBy(env.enclClass.sym)) { + log.error(tree, Errors.CantRefBeforeCtorCalled(tree.constructor)); + } + + /*if (tree.encl != null) { + Symbol enclSym = TreeInfo.symbolFor(tree.encl); + if (enclSym.owner == env.enclClass.sym) { + // using this? + if (TreeInfo.isExplicitThisReference(types, (ClassType) env.enclClass.sym.type, tree.encl)) { + log.error(tree.encl, Errors.CantRefBeforeCtorCalled(enclSym)); + } + } + }*/ + } + } + + @Override + public void visitAssign(JCAssign tree) { + super.visitAssign(tree); + if (ctorPrologue && tree.rhs.type.constValue() == null) { + analyzeTree(tree.rhs); + } + } + + @Override + public void visitVarDef(JCVariableDecl tree) { + super.visitVarDef(tree); + if (ctorPrologue && tree.init != null && tree.init.type.constValue() == null) { + analyzeTree(tree.init); + } + } + + JCTree filter(JCTree tree) { + tree = TreeInfo.skipParens(tree); + if (tree.hasTag(TYPECAST)) { + tree = filter(((JCTypeCast)tree).expr); + } + return tree; + } + + void analyzeTree(JCTree jcTree) { + if (jcTree.toString().equals("(int)e.size")) { + //System.err.println("stop here Attr"); + } + jcTree = filter(jcTree); + java.util.List symbols = TreeInfo.symbolsFor(jcTree); + for (TreeInfo.SymAndTree symAndTree : symbols) { + Symbol sym = symAndTree.symbol(); + JCTree tree = filter(symAndTree.tree()); + if (!sym.isStatic() && !isMethodParam(tree)) { + if (sym.name == names._this || sym.name == names._super) { + if (TreeInfo.isExplicitThisReference(types, (ClassType)env.enclClass.sym.type, tree)) { + log.error(tree, Errors.CantRefBeforeCtorCalled(sym)); + } + } else { + if (sym != null && + sym.owner != env.enclClass.sym && + sym.kind == VAR && + sym.owner.kind == TYP) { + //Assert.check(tree.hasTag(IDENT) || tree.hasTag(SELECT), "unexpected tree " + tree + " with tag " + tree.getTag()); + if (!tree.hasTag(IDENT) && !tree.hasTag(SELECT)) { + //tree = filter(tree); + throw new AssertionError("unexpected tree " + tree + " with tag " + tree.getTag()); + } + Symbol owner = tree.hasTag(IDENT) ? sym.owner : ((JCFieldAccess)tree).selected.type.tsym; + if (env.enclClass.sym.isSubClass(owner, types)) { + log.error(tree, Errors.CantRefBeforeCtorCalled(sym)); + } + //if () { //env.enclClass.sym.isEnclosedBy((ClassSymbol) sym.owner) + // do nothing + //} else { + // log.error(tree, Errors.CantRefBeforeCtorCalled(sym)); + //} + } + } + } + } + } + + boolean isMethodParam(JCTree tree) { + JCTree treeToCheck = null; + if (tree.hasTag(IDENT)) { + treeToCheck = tree; + } else if (tree instanceof JCFieldAccess) { + JCFieldAccess fa = (JCFieldAccess) tree; + while (fa.selected.hasTag(SELECT)) { + fa = (JCFieldAccess)fa.selected; + } + treeToCheck = fa; + } + if (treeToCheck != null) { + Symbol sym = TreeInfo.symbolFor(treeToCheck instanceof JCFieldAccess fa ? fa.selected : treeToCheck); + if (sym != null){ + return sym.owner.kind == MTH; + } + } + return false; + } + + class FindEnclosingSelect extends TreeScanner { + JCTree treeToLookFor; + JCFieldAccess enclosingSelect = null; + + public JCFieldAccess scan(JCTree treeToLookFor, JCTree tree) { + this.treeToLookFor = treeToLookFor; + super.scan(tree); + return enclosingSelect; + } + + @Override + public void visitSelect(JCFieldAccess tree) { + if (tree.selected == treeToLookFor) { + enclosingSelect = tree; + // this select could be part of an enclosing select + treeToLookFor = tree; + } else { + scan(tree.selected); + } + } + } + } + public void visitVarDef(JCVariableDecl tree) { // Local variables have not been entered yet, so we need to do it now: if (env.info.scope.owner.kind == MTH || env.info.scope.owner.kind == VAR) { diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java index ad7a66ae7ee..be4381beb4d 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java @@ -1463,6 +1463,9 @@ Symbol findField(Env env, Type site, Name name, TypeSymbol c) { + if (env.tree.toString().contains("EventRequestManagerImpl.this.vm") && name.toString().equals("vm")) { + //System.err.println("stop here"); + } while (c.type.hasTag(TYPEVAR)) c = c.type.getUpperBound().tsym; Symbol bestSoFar = varNotFound; @@ -1537,16 +1540,6 @@ Symbol findVar(DiagnosticPosition pos, Env env, Name name) { (sym.flags() & STATIC) == 0) { if (staticOnly) return new StaticError(sym); - if (env1.info.ctorPrologue && !isAllowedEarlyReference(pos, env1, (VarSymbol)sym)) { - if (!env.tree.hasTag(ASSIGN) || !TreeInfo.isIdentOrThisDotIdent(((JCAssign)env.tree).lhs)) { - if (!sym.isStrictInstance()) { - return new RefBeforeCtorCalledError(sym); - } else { - localProxyVarsGen.addStrictFieldReadInPrologue(env.enclMethod, sym); - return sym; - } - } - } } return sym; } else { @@ -2054,8 +2047,8 @@ Symbol findFun(Env env, Name name, (sym.flags() & STATIC) == 0) { if (staticOnly) return new StaticError(sym); - if (env1.info.ctorPrologue && env1 == env) - return new RefBeforeCtorCalledError(sym); + /*if (env1.info.ctorPrologue && env1 == env) + return new RefBeforeCtorCalledError(sym);*/ } return sym; } else { @@ -3826,9 +3819,6 @@ Symbol findSelfContaining(DiagnosticPosition pos, if (staticOnly) { // current class is not an inner class, stop search return new StaticError(sym); - } else if (env1.info.ctorPrologue && !isAllowedEarlyReference(pos, env1, (VarSymbol)sym)) { - // early construction context, stop search - return new RefBeforeCtorCalledError(sym); } else { // found it return sym; @@ -3887,8 +3877,6 @@ Symbol resolveSelf(DiagnosticPosition pos, if (sym != null) { if (staticOnly) sym = new StaticError(sym); - else if (env1.info.ctorPrologue && !isAllowedEarlyReference(pos, env1, (VarSymbol)sym)) - sym = new RefBeforeCtorCalledError(sym); return accessBase(sym, pos, env.enclClass.sym.type, name, true); } @@ -3902,8 +3890,8 @@ else if (env1.info.ctorPrologue && !isAllowedEarlyReference(pos, env1, (VarSymbo //this might be a default super call if one of the superinterfaces is 'c' for (Type t : pruneInterfaces(env.enclClass.type)) { if (t.tsym == c) { - if (env.info.ctorPrologue) - log.error(pos, Errors.CantRefBeforeCtorCalled(name)); + /*if (env.info.ctorPrologue) + log.error(pos, Errors.CantRefBeforeCtorCalled(name));*/ env.info.defaultSuperCallSite = t; return new VarSymbol(0, names._super, types.asSuper(env.enclClass.type, c), env.enclClass.sym); @@ -3940,64 +3928,6 @@ private List pruneInterfaces(Type t) { return result.toList(); } - /** - * Determine if an early instance field reference may appear in a constructor prologue. - * - *

- * This is only allowed when: - * - The field is being assigned a value (i.e., written but not read) - * - The field is not inherited from a superclass - * - The assignment is not within a lambda, because that would require - * capturing 'this' which is not allowed prior to super(). - * - *

- * Note, this method doesn't catch all such scenarios, because this method - * is invoked for symbol "x" only for "x = 42" but not for "this.x = 42". - * We also don't verify that the field has no initializer, which is required. - * To catch those cases, we rely on similar logic in Attr.checkAssignable(). - */ - private boolean isAllowedEarlyReference(DiagnosticPosition pos, Env env, VarSymbol v) { - - // Check assumptions - Assert.check(env.info.ctorPrologue); - Assert.check((v.flags_field & STATIC) == 0); - - // The symbol must appear in the LHS of an assignment statement - if (!(env.tree instanceof JCAssign assign)) - return false; - - // The assignment statement must not be within a lambda - if (env.info.isLambda) - return false; - - // Get the symbol's qualifier, if any - JCExpression lhs = TreeInfo.skipParens(assign.lhs); - JCExpression base; - switch (lhs.getTag()) { - case IDENT: - base = null; - break; - case SELECT: - JCFieldAccess select = (JCFieldAccess)lhs; - base = select.selected; - if (!TreeInfo.isExplicitThisReference(types, (ClassType)env.enclClass.type, base)) - return false; - break; - default: - return false; - } - - // If an early reference, the field must not be declared in a superclass - if (isEarlyReference(env, base, v) && v.owner != env.enclClass.sym) - return false; - - // The flexible constructors feature must be enabled - preview.checkSourceLevel(pos, Feature.FLEXIBLE_CONSTRUCTORS); - - // OK - return true; - } - /** * Determine if the variable appearance constitutes an early reference to the current class. * diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java index 5e3b043fb11..8dbfb5ca19e 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java @@ -50,6 +50,7 @@ import javax.lang.model.element.ElementKind; import javax.tools.JavaFileObject; +import java.util.ArrayList; import java.util.function.Function; import java.util.function.Predicate; import java.util.function.ToIntFunction; @@ -964,6 +965,30 @@ public static Name fullName(JCTree tree) { } } + public record SymAndTree(Symbol symbol, JCTree tree) {} + + public static java.util.List symbolsFor(JCTree node) { + java.util.List result = new ArrayList<>(); + new TreeScanner() { + @Override + public void scan(JCTree tree) { + super.scan(tree); + if (tree != null) { + Symbol symbol = TreeInfo.symbolFor(tree); + if (symbol != null) { + result.add(new SymAndTree(symbol, tree)); + } + } + } + + @Override + public void visitSelect(JCFieldAccess tree) { + // do not go deeper + } + }.scan(node); + return result; + } + public static Symbol symbolFor(JCTree node) { Symbol sym = symbolForImpl(node); @@ -1007,6 +1032,8 @@ private static Symbol symbolForImpl(JCTree node) { if (node.type != null) return node.type.tsym; return null; + case TYPECAST: + return symbolFor(((JCTypeCast)node).expr); default: return null; } diff --git a/test/jdk/java/io/Serializable/maskSyntheticModifier/Foo.class b/test/jdk/java/io/Serializable/maskSyntheticModifier/Foo.class index 1777af8b136a3a0f7a1622fa0482c100b5b2bf0e..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644 GIT binary patch literal 0 HcmV?d00001 literal 667 zcmZuv-%k@k5dMai?)5lnsYL{oUlwR<(k8yv@Pafksr8|TgvaZ#981cr*=~*c5Bchk zM2IH(Xu=;wn7!7tF+SYx%{MdO%r~<)w?BRXXrS)nAyx&}1lE1b;gOFF9{X6pMjk#k zJ#6`WZwu@QJQ1i6R-!>T99AyEcVT4^CUNCuVr481VX5Q5rURRYE~rJw_dX={Tv`;WNDtsN7xhx$|!3LTZm?&z{F&6}`4U?exLK-jI$F!robN!+TP>|vR(^-o`2ZQFX3oF2W8+xf0U&-MxjM*qxXZ24;LRkLappLQ4t6Kme;Lmd{^IhP*gEtMQgY6Rkwb*vZ zdi@HyuMmGwD0$b&pL~P(lp>uk>?YjjbCF*Nm?p~vYfRxe$(-(pp0UpnmFm}^&z+yh foIL%G>=ovJb2d0vdp1tEx#()~n-Fw#t5n(2SJ5?u5H`cdMY zZaRxMXYM<^H^;x<1Ary2GK9EHkS8bv;zw=tuoAeQS6^~3%dIqRSr1m5_Tlw*BM?3H zpGu&pv{7%aYm{BfX3He4b!+6{EIFKeHLH7PKh%r%?c&+E?!DhBXBU1lC;4Q82qUWJ yu0Vd?>|;z3@Q?lo5`ET~uNhOHCwKQZKM>z1Az{rZ04b#m7o>n3kUfnt;f;U7#xWcK diff --git a/test/jdk/java/lang/Class/forName/classes/0.class b/test/jdk/java/lang/Class/forName/classes/0.class index b5b6c8f2b56dc600192faf40bd74200dfdc01889..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644 GIT binary patch literal 0 HcmV?d00001 literal 408 zcmZutyH3ME5S&dMzc3^uI6PBOAQ_6-)Il^zh#~?cBN{3@IYk%wfs75}v!DQpf)C)M z5PMD$MdFIxz1i8>x%>J3`UY@{fejsP3mt5l=-TLE%YbX3Ptea~Cd+d|(>uN=XczfZ z5ZYsziR&tjMR6C!2_sq>$&AqV9>(+NIr5VzoB3f`$ZR%JgLar##Y9|6Mb?9%A~`T% z8rXKQgI$7iC6Xi$Uh*QD4h`%%*vA2Z0zzl0c@xjYq+Ef**QZjXY%#C6;Vulw+`r}R zC3_H2IwJIHja8UnJStMc)?M#E=Qu=*KS!Mgm=2Sp#kT=x;@mp<1if*=Z{(;iK&Gt0 e;aX9T>QTUYN2A;PfVQOD+(NCYbl16VVB-%`olool diff --git a/test/jdk/java/lang/Class/forName/classes/3.class b/test/jdk/java/lang/Class/forName/classes/3.class index 4d183b07c2c1c71e7ab4719eac8371a2e343298f..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644 GIT binary patch literal 0 HcmV?d00001 literal 408 zcmZutyH3ME5S&dMzc3^uI6PBOAQ_5S$Yl@>5~7Fz$%ux^PEOH9ejsCm_$(+uqTmDg zD8!yqM3J~+cW-ufcJ6+DzrF#SVqil@+d>DMCb~9y*fQW6=o9oanaT2;(DaV)3ED+I z6@>O!X5zX^V^Q2ial(j}MlvJxy@&BUdXD@g%4U987BZWS)Sw;aRWT8lQjzsws7MYB zm|mGRT!|#fgO|KWrb7dJ4)$?Cpn%X>YTm?iF)3G|@b#$_DO=1dZnz5rGWTzJ zd&wR|l#U3!T4NO^7>|mSuyxn_&p8g!;?Gg10j9&`Xz^{pnK-vjK0$9>@EbYm3y>*m faJW{~qk0su-qGkbKcFq?Hn&i#D&2Li8`$^*ThmYV diff --git a/test/jdk/java/lang/Class/forName/classes/Z.class b/test/jdk/java/lang/Class/forName/classes/Z.class index cedf4a38923ee73b88f8fe1c3bc11d171aad8731..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644 GIT binary patch literal 0 HcmV?d00001 literal 408 zcmZutO-sW-5Pj38`7+wtn)+F=2O)ZB@LcgCh=-y=#6vwL?NYYnLt>)%v-F_g!5`p{ z5@*vxDY%E3**9eFp-c%~?_o3#pF=+m)0rO>xlCt6HE0J}nNP%}RAhZTP$UNi zOat2vcCbruu0$MXhc8(kPX`9}9PHzOKx0B{sd*F4#iUq)g4d@)By2G&x#2Dh$jrax z?FD-fVKO9iDvec`U_2^P%+_7+Kj-M9!Jnf}4NQm0(c)W=GjVR5e1hJ%;5TyA7a&vC f;Bc*|N7X1`y`$Eye?VK(ZEm4bRl4h3*Rb&inB!0| diff --git a/test/jdk/java/lang/Class/forName/classes/comma.class b/test/jdk/java/lang/Class/forName/classes/comma.class index 7d21d7106f724bbcde041431b9669ed5e8856287..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644 GIT binary patch literal 0 HcmV?d00001 literal 408 zcmZutO-sW-5Pj38`7+wtn)=y;2O&ym@LcgCh=-y=#EYk-UCNexNK6!emL3#5_yhb= z;%s^-1@|yB`{vD?xBK(^^$p+@0~|HVeYCklAdc2JJAfiixt-IcT&T)tqe~vm0FdZgGi*EzY#JP3y33}s#-^fv4fJ|9~ e!?mIw)uVv*jz+in0c}aQxrJI)>8^9#z{Vd&RZrjm diff --git a/test/jdk/java/lang/Class/forName/classes/hyphen.class b/test/jdk/java/lang/Class/forName/classes/hyphen.class index 9ca321382fb1243663ebc139a557e1c795e5dd37..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644 GIT binary patch literal 0 HcmV?d00001 literal 408 zcmZutO-sW-5Pj38`7+wtn)=y;2O$b+@LcgCh=-y=#EYk-UCNexNK6!emL3#5_yhb= z;%s^-1@|yB`{vD?xBK(^^$p+@0~|HVeYCklAdc2JJAfiixt-IcT&T)tqe~vm0FdZgGi*EzY#JP3y33}s#-^fv4fJ|9~ e!?mIw)uVv*jz+in0c}aQxrJI)>8^9#z{Vd*XHVk* diff --git a/test/jdk/java/lang/Class/forName/classes/left-square.class b/test/jdk/java/lang/Class/forName/classes/left-square.class index 8d5009df65ee43eedb4b0686ee374b45de6eb1f5..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644 GIT binary patch literal 0 HcmV?d00001 literal 408 zcmZutyH3ME5S(=!+cAcO1czq|3M4}ji#mt~2~k9VWJKf2PEOH9eniFw@mWxSM8OB} zQHVXKh$3;t?%wR|?A-nQetiQt$H0bxb_*SBTj<*8VaJ4PqE9d`WG2f?Lc=?KB zSSEHI>|vka+=wK}!|df$6X~w)i&SOq`o%pP)A`_>CNmCCHQw fI9x00Nj(a*-l26HAJA8Hn_H+=mF_0j8n*rb)}v5u diff --git a/test/jdk/java/lang/Class/forName/classes/period.class b/test/jdk/java/lang/Class/forName/classes/period.class index 2581aab2c6da4282349e48654c2a07dbdd2ccfb5..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644 GIT binary patch literal 0 HcmV?d00001 literal 408 zcmZutyH3ME5S(=!zc3^uI6PBOAQ=i<)Il^zh#~?cBN{3@IYk%wfs75}v!DQpf)C)M z5PMD$MdFIxz1i8>x%>J3`UY@{p#uXQ8(nN#=sD dTr28PGYZ)6(0Z*8=u5i8Ei|f1cb#hu8-GlBPv!ss diff --git a/test/jdk/java/lang/Class/forName/classes/plus.class b/test/jdk/java/lang/Class/forName/classes/plus.class index 32037d725d16236f8b10542526d9080f3dfc3c59..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644 GIT binary patch literal 0 HcmV?d00001 literal 408 zcmZutO-sW-5Pj38`7+wtn)=y;2O%10@LcgCh=-y=#EYk-UCNexNK6!emL3#5_yhb= z;%s^-1@|yB`{vD?xBK(^^$p+@0~|HVeYCklAdc2JJAfiixt-IcT&T)tqe~vm0FdZgGi*EzY#JP3y33}s#-^fv4fJ|9~ e!?mIw)uVv*jz+in0c}aQxrJI)>8^9#z{Vd#Lr>iR diff --git a/test/jdk/java/lang/Class/forName/classes/right-square.class b/test/jdk/java/lang/Class/forName/classes/right-square.class index 0b61551e9025c23664e5a714d35927d1f73d17c7..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644 GIT binary patch literal 0 HcmV?d00001 literal 408 zcmZutyH3ME5S&dMzc3^uI6PBOAQ_5S)Il^zh#~?cBO2twPEOH9ejsCm_$(+uqTmDg zD8!yqM3J~+cW-ufcJ6+DzrF#SVqil@+d>DMCb~9y*fQW6=o9oanaT2;(DaV)3ED+I z6@>O!X5zX^V^Q2ial(j}MlvJxy@&BUdXD@g%4U907BZWS)Sw;YRWT8lQjzs=s7MYB zm|mGRT!|#f!|mSuyxn_&p8g!;?Gg10j9&`Xz^{pnK-vjK0$9>@EbYm3y>*m faJW{~qk0su-qGkbKcFq?Hn&i#D&2Li8`$^*+{aLJ diff --git a/test/jdk/java/lang/Class/forName/classes/semicolon.class b/test/jdk/java/lang/Class/forName/classes/semicolon.class index a1524080ae3be1702a1a7c2b4c4400df09d39ec8..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644 GIT binary patch literal 0 HcmV?d00001 literal 408 zcmZutJx{|h5PeS5I0=E4mXyy93`l{Y5pxg=5@M(TDTswBX|2jt5~GlS_*pQ3#J~^W zM$+ktTWI zusOCp>|mF{yAoNZq8C+W(-Fs>hkYC{u!y0%)VxXOVp6R@@#|A1a78RhoLC)gVm^hS!-0wl^B eJgPPIs2K&EcNo3a2h1hir4|}ht-DUOfsH?OV^9qM diff --git a/test/jdk/sun/misc/Hello.class b/test/jdk/sun/misc/Hello.class index 07bb8bd4bb089a2ceb50549d11548fbb806310ab..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644 GIT binary patch literal 0 HcmV?d00001 literal 401 zcmZvY%SyvQ6o&uFZJIIKnwolFxDcYCd4P%=L0l9SB5qtw>QJWSQerCjSh`Sf;RE#@4j1{PN;&#O}d z2H@y$3<7Loi@|L(9NPhQu*=X}G`q>BYTPVI>C0223ffK8HAD0_Sy#y|jcsVSlEsjr z-}YFR8TiaVIqe+9|E-Jzxb!RLSRfo7vOeAR$usiq@dwx|1@s=WUMq4!RuE8Z(8IPA Y@ZVsC_B)&fE+|C_>M96crP#vSFLNSJ-~a#s diff --git a/test/jdk/sun/security/tools/jarsigner/oldsig/A.class b/test/jdk/sun/security/tools/jarsigner/oldsig/A.class index 88a98f09e00f1dc61bff002e97393e4351e5c6d4..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644 GIT binary patch literal 0 HcmV?d00001 literal 176 zcmX^0Z`VEs1_mPrUM>b^1}=66ZgvJ9Mg}&U%)HDJJ4Oa(4b3n{1{UZ1lvG9rexJ;| zRKL>Pq|~C2#H1Xc2v=}^X;E^jTPBFZ=BSsISeD4cz{0@F$iV2x$RGgX>*plqrR)1A zWu+#UFeorE0qp?+Mj!?%1k!9kmMoA4iLh#IXJFh2mSzW%Y+yl<6bF#U#J~vvV?P{> diff --git a/test/langtools/tools/javac/SuperInit/EarlyAssignments.out b/test/langtools/tools/javac/SuperInit/EarlyAssignments.out index 38182c2d312..0772bdef949 100644 --- a/test/langtools/tools/javac/SuperInit/EarlyAssignments.out +++ b/test/langtools/tools/javac/SuperInit/EarlyAssignments.out @@ -1,7 +1,4 @@ -EarlyAssignments.java:21:17: compiler.err.cant.ref.before.ctor.called: x -EarlyAssignments.java:22:17: compiler.err.cant.ref.before.ctor.called: this -EarlyAssignments.java:23:23: compiler.err.cant.ref.before.ctor.called: this -EarlyAssignments.java:31:21: compiler.err.cant.ref.before.ctor.called: super +EarlyAssignments.java:31:26: compiler.err.cant.ref.before.ctor.called: x EarlyAssignments.java:32:21: compiler.err.cant.ref.before.ctor.called: x EarlyAssignments.java:33:26: compiler.err.cant.ref.before.ctor.called: x EarlyAssignments.java:34:34: compiler.err.cant.ref.before.ctor.called: x @@ -13,17 +10,13 @@ EarlyAssignments.java:66:13: compiler.err.cant.ref.before.ctor.called: x EarlyAssignments.java:67:17: compiler.err.cant.ref.before.ctor.called: x EarlyAssignments.java:68:25: compiler.err.cant.ref.before.ctor.called: this EarlyAssignments.java:69:31: compiler.err.cant.ref.before.ctor.called: this -EarlyAssignments.java:98:17: compiler.err.cant.ref.before.ctor.called: x -EarlyAssignments.java:104:22: compiler.err.cant.ref.before.ctor.called: this -EarlyAssignments.java:110:35: compiler.err.cant.ref.before.ctor.called: this EarlyAssignments.java:119:17: compiler.err.cant.ref.before.ctor.called: x EarlyAssignments.java:124:22: compiler.err.cant.ref.before.ctor.called: x EarlyAssignments.java:129:29: compiler.err.cant.ref.before.ctor.called: x -EarlyAssignments.java:134:17: compiler.err.cant.ref.before.ctor.called: super -EarlyAssignments.java:139:23: compiler.err.cant.ref.before.ctor.called: this -EarlyAssignments.java:148:13: compiler.err.cant.assign.initialized.before.ctor.called: x +EarlyAssignments.java:134:22: compiler.err.cant.ref.before.ctor.called: x +EarlyAssignments.java:139:28: compiler.err.cant.ref.before.ctor.called: x EarlyAssignments.java:157:13: compiler.err.cant.assign.val.to.var: final, x EarlyAssignments.java:168:13: compiler.err.cant.ref.before.ctor.called: this - compiler.note.preview.filename: EarlyAssignments.java, DEFAULT - compiler.note.preview.recompile -26 errors +19 errors diff --git a/test/langtools/tools/javac/SuperInit/SuperInitFails.out b/test/langtools/tools/javac/SuperInit/SuperInitFails.out index 4394a6741c3..8ee4cfafe5b 100644 --- a/test/langtools/tools/javac/SuperInit/SuperInitFails.out +++ b/test/langtools/tools/javac/SuperInit/SuperInitFails.out @@ -1,13 +1,12 @@ SuperInitFails.java:57:9: compiler.err.cant.ref.before.ctor.called: hashCode() -SuperInitFails.java:62:9: compiler.err.cant.ref.before.ctor.called: this -SuperInitFails.java:67:9: compiler.err.cant.ref.before.ctor.called: super -SuperInitFails.java:72:23: compiler.err.cant.ref.before.ctor.called: this -SuperInitFails.java:77:23: compiler.err.cant.ref.before.ctor.called: super -SuperInitFails.java:94:9: compiler.err.cant.ref.before.ctor.called: this +SuperInitFails.java:62:13: compiler.err.cant.ref.before.ctor.called: hashCode() +SuperInitFails.java:67:14: compiler.err.cant.ref.before.ctor.called: hashCode() +SuperInitFails.java:72:28: compiler.err.cant.ref.before.ctor.called: hashCode() +SuperInitFails.java:77:29: compiler.err.cant.ref.before.ctor.called: hashCode() SuperInitFails.java:99:33: compiler.err.cant.ref.before.ctor.called: this SuperInitFails.java:104:14: compiler.err.cant.ref.before.ctor.called: this SuperInitFails.java:108:20: compiler.err.not.encl.class: java.lang.Object -SuperInitFails.java:112:17: compiler.err.cant.ref.before.ctor.called: super +SuperInitFails.java:112:23: compiler.err.cant.ref.before.ctor.called: spliterator() SuperInitFails.java:119:22: compiler.err.call.must.only.appear.in.ctor SuperInitFails.java:125:9: compiler.err.cant.ref.before.ctor.called: this SuperInitFails.java:133:9: compiler.err.non.canonical.constructor.invoke.another.constructor: SuperInitFails.Record1 From 68bd63e862aab3b473fc534d73476b96f2cfeca6 Mon Sep 17 00:00:00 2001 From: Vicente Romero Date: Thu, 14 Aug 2025 12:50:13 -0400 Subject: [PATCH 02/10] additional experiments --- .../com/sun/tools/javac/comp/Attr.java | 114 +++++++++++------- .../com/sun/tools/javac/tree/TreeInfo.java | 11 ++ ...nvalidThisAndSuperInConstructorArgTest.out | 12 +- .../javac/SuperInit/EarlyAssignments.out | 2 +- .../SuperInit/EarlyIndirectOuterCapture.java | 4 +- .../SuperInit/EarlyIndirectOuterCapture.out | 2 - .../tools/javac/SuperInit/EarlyLocalClass.out | 2 +- .../tools/javac/SuperInit/SuperInitFails.java | 2 +- .../tools/javac/SuperInit/SuperInitFails.out | 7 +- .../SuperInit/ValueClassSuperInitFails.out | 19 +-- .../CantReferenceBeforeConstructorTest.out | 2 +- 11 files changed, 108 insertions(+), 69 deletions(-) delete mode 100644 test/langtools/tools/javac/SuperInit/EarlyIndirectOuterCapture.out 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 8517b19bf78..f62d59a4e1c 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 @@ -1251,8 +1251,19 @@ public void visitMethodDef(JCMethodDecl tree) { // Attribute method body. attribStat(tree.body, localEnv); if (isConstructor) { - CtorPrologueVisitor ctorPrologueVisitor = new CtorPrologueVisitor(localEnv); - ctorPrologueVisitor.scan(tree.body); + ListBuffer prologueCode = new ListBuffer<>(); + for (JCTree stat : tree.body.stats) { + prologueCode.add(stat); + if (stat instanceof JCExpressionStatement expStmt && + expStmt.expr instanceof JCMethodInvocation mi && + TreeInfo.isConstructorCall(mi)) { + break; + } + } + if (!prologueCode.isEmpty()) { + CtorPrologueVisitor ctorPrologueVisitor = new CtorPrologueVisitor(localEnv); + ctorPrologueVisitor.scan(prologueCode.toList()); + } } } @@ -1267,74 +1278,89 @@ public void visitMethodDef(JCMethodDecl tree) { class CtorPrologueVisitor extends TreeScanner { Env localEnv; - boolean ctorPrologue = true; - CtorPrologueVisitor(Env localEnv) { this.localEnv = localEnv; } + @Override + public void visitLambda(JCLambda lambda) { + super.visitLambda(lambda); + java.util.List symbols = TreeInfo.symbolsFor(lambda.body); + for (TreeInfo.SymAndTree symAndTree : symbols) { + Symbol sym = symAndTree.symbol(); + JCTree tree = filter(symAndTree.tree()); + if (sym.kind == VAR && rs.isEarlyReference(localEnv, tree instanceof JCFieldAccess fa ? fa.selected : null, (VarSymbol) sym)) { + log.error(tree, Errors.CantRefBeforeCtorCalled(sym)); + } + } + } + + @Override + public void visitClassDef(JCClassDecl classDecl) { + super.visitClassDef(classDecl); + // local class in prologue + java.util.List symbols = TreeInfo.symbolsFor(classDecl.defs); + for (TreeInfo.SymAndTree symAndTree : symbols) { + Symbol sym = symAndTree.symbol(); + JCTree tree = filter(symAndTree.tree()); + if (sym.kind == VAR && rs.isEarlyReference(localEnv, tree instanceof JCFieldAccess fa ? fa.selected : null, (VarSymbol) sym)) { + log.error(tree, Errors.CantRefBeforeCtorCalled(sym)); + } + } + } + @Override public void visitApply(JCMethodInvocation tree) { super.visitApply(tree); Name name = TreeInfo.name(tree.meth); boolean isConstructorCall = name == names._this || name == names._super; - if (ctorPrologue) { - Symbol msym = TreeInfo.symbolFor(tree.meth); - if (!isConstructorCall && !msym.isStatic()) { - if (msym.owner == env.enclClass.sym) { - // instance method? - if (tree.meth instanceof JCFieldAccess fa) { - if (TreeInfo.isExplicitThisReference(types, (ClassType)env.enclClass.sym.type, fa.selected)) { - log.error(tree.meth, Errors.CantRefBeforeCtorCalled(msym)); - } - } else { + Symbol msym = TreeInfo.symbolFor(tree.meth); + if (!isConstructorCall && !msym.isStatic()) { + if (msym.owner == env.enclClass.sym) { + // instance method? + if (tree.meth instanceof JCFieldAccess fa) { + if (TreeInfo.isExplicitThisReference(types, (ClassType)env.enclClass.sym.type, fa.selected)) { log.error(tree.meth, Errors.CantRefBeforeCtorCalled(msym)); } - } else if (msym.isMemberOf(env.enclClass.sym, types)){ - // where we are dealing with an inherited method, probably an error too - if (tree.meth instanceof JCFieldAccess fa) { - if (TreeInfo.isExplicitThisReference(types, (ClassType)env.enclClass.sym.type, fa.selected)) { - log.error(tree.meth, Errors.CantRefBeforeCtorCalled(msym)); - } - } else { + } else { + log.error(tree.meth, Errors.CantRefBeforeCtorCalled(msym)); + } + } else if (msym.isMemberOf(env.enclClass.sym, types)){ + // where we are dealing with an inherited method, probably an error too + if (tree.meth instanceof JCFieldAccess fa) { + if (TreeInfo.isExplicitThisReference(types, (ClassType)env.enclClass.sym.type, fa.selected)) { log.error(tree.meth, Errors.CantRefBeforeCtorCalled(msym)); } + } else { + log.error(tree.meth, Errors.CantRefBeforeCtorCalled(msym)); } } - // we still need to check the args - for (JCExpression arg : tree.args) { - analyzeTree(arg); - } } if (isConstructorCall) { - ctorPrologue = false; + if (tree.meth instanceof JCFieldAccess fa) { + if (TreeInfo.isExplicitThisReference(types, (ClassType)env.enclClass.sym.type, fa.selected)) { + log.error(tree.meth, Errors.CantRefBeforeCtorCalled(msym)); + } + } + } + // we still need to check the args + for (JCExpression arg : tree.args) { + analyzeTree(arg); } } @Override public void visitNewClass(JCNewClass tree) { super.visitNewClass(tree); - if (ctorPrologue) { - if (tree.type.tsym.isEnclosedBy(env.enclClass.sym)) { - log.error(tree, Errors.CantRefBeforeCtorCalled(tree.constructor)); - } - - /*if (tree.encl != null) { - Symbol enclSym = TreeInfo.symbolFor(tree.encl); - if (enclSym.owner == env.enclClass.sym) { - // using this? - if (TreeInfo.isExplicitThisReference(types, (ClassType) env.enclClass.sym.type, tree.encl)) { - log.error(tree.encl, Errors.CantRefBeforeCtorCalled(enclSym)); - } - } - }*/ + if (tree.type.tsym.isEnclosedBy(env.enclClass.sym) && !tree.type.tsym.isStatic() && !tree.type.tsym.isDirectlyOrIndirectlyLocal()) { + log.error(tree, Errors.CantRefBeforeCtorCalled(tree.constructor)); } } @Override public void visitAssign(JCAssign tree) { super.visitAssign(tree); - if (ctorPrologue && tree.rhs.type.constValue() == null) { + if (tree.rhs.type.constValue() == null) { analyzeTree(tree.rhs); } } @@ -1342,7 +1368,7 @@ public void visitAssign(JCAssign tree) { @Override public void visitVarDef(JCVariableDecl tree) { super.visitVarDef(tree); - if (ctorPrologue && tree.init != null && tree.init.type.constValue() == null) { + if (tree.init != null && tree.init.type.constValue() == null) { analyzeTree(tree.init); } } @@ -1371,6 +1397,7 @@ void analyzeTree(JCTree jcTree) { } } else { if (sym != null && + !sym.owner.isAnonymous() && sym.owner != env.enclClass.sym && sym.kind == VAR && sym.owner.kind == TYP) { @@ -1413,7 +1440,7 @@ boolean isMethodParam(JCTree tree) { } return false; } - +/* class FindEnclosingSelect extends TreeScanner { JCTree treeToLookFor; JCFieldAccess enclosingSelect = null; @@ -1435,6 +1462,7 @@ public void visitSelect(JCFieldAccess tree) { } } } + */ } public void visitVarDef(JCVariableDecl tree) { diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java index 8dbfb5ca19e..528c1a927ab 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java @@ -967,6 +967,17 @@ public static Name fullName(JCTree tree) { public record SymAndTree(Symbol symbol, JCTree tree) {} + public static java.util.List symbolsFor(List nodes) { + java.util.List result = new ArrayList<>(); + for (JCTree node : nodes) { + java.util.List partialResult = symbolsFor(node); + if (!partialResult.isEmpty()) { + result.addAll(partialResult); + } + } + return result; + } + public static java.util.List symbolsFor(JCTree node) { java.util.List result = new ArrayList<>(); new TreeScanner() { diff --git a/test/langtools/tools/javac/8278078/InvalidThisAndSuperInConstructorArgTest.out b/test/langtools/tools/javac/8278078/InvalidThisAndSuperInConstructorArgTest.out index 1109eb0fdc4..4fd6ebf1323 100644 --- a/test/langtools/tools/javac/8278078/InvalidThisAndSuperInConstructorArgTest.out +++ b/test/langtools/tools/javac/8278078/InvalidThisAndSuperInConstructorArgTest.out @@ -1,14 +1,14 @@ -InvalidThisAndSuperInConstructorArgTest.java:23:29: compiler.err.cant.ref.before.ctor.called: super -InvalidThisAndSuperInConstructorArgTest.java:26:28: compiler.err.cant.ref.before.ctor.called: super -InvalidThisAndSuperInConstructorArgTest.java:29:29: compiler.err.cant.ref.before.ctor.called: this -InvalidThisAndSuperInConstructorArgTest.java:32:28: compiler.err.cant.ref.before.ctor.called: this +InvalidThisAndSuperInConstructorArgTest.java:23:35: compiler.err.cant.ref.before.ctor.called: toString() +InvalidThisAndSuperInConstructorArgTest.java:26:34: compiler.err.cant.ref.before.ctor.called: toString() +InvalidThisAndSuperInConstructorArgTest.java:29:34: compiler.err.cant.ref.before.ctor.called: toString() +InvalidThisAndSuperInConstructorArgTest.java:32:33: compiler.err.cant.ref.before.ctor.called: toString() InvalidThisAndSuperInConstructorArgTest.java:35:33: compiler.err.not.encl.class: java.lang.AssertionError InvalidThisAndSuperInConstructorArgTest.java:38:32: compiler.err.not.encl.class: java.lang.AssertionError InvalidThisAndSuperInConstructorArgTest.java:41:33: compiler.err.not.encl.class: java.lang.AssertionError InvalidThisAndSuperInConstructorArgTest.java:44:32: compiler.err.not.encl.class: java.lang.AssertionError -InvalidThisAndSuperInConstructorArgTest.java:47:38: compiler.err.cant.ref.before.ctor.called: super +InvalidThisAndSuperInConstructorArgTest.java:47:44: compiler.err.cant.ref.before.ctor.called: get() InvalidThisAndSuperInConstructorArgTest.java:50:39: compiler.err.not.encl.class: InvalidThisAndSuperInConstructorArgTest.InterfaceWithDefault InvalidThisAndSuperInConstructorArgTest.java:53:38: compiler.err.not.encl.class: InvalidThisAndSuperInConstructorArgTest.InterfaceWithDefault -InvalidThisAndSuperInConstructorArgTest.java:56:39: compiler.err.cant.ref.before.ctor.called: super +InvalidThisAndSuperInConstructorArgTest.java:56:45: compiler.err.cant.ref.before.ctor.called: get() InvalidThisAndSuperInConstructorArgTest.java:59:28: compiler.err.cant.ref.before.ctor.called: this 13 errors diff --git a/test/langtools/tools/javac/SuperInit/EarlyAssignments.out b/test/langtools/tools/javac/SuperInit/EarlyAssignments.out index 0772bdef949..29e4989384e 100644 --- a/test/langtools/tools/javac/SuperInit/EarlyAssignments.out +++ b/test/langtools/tools/javac/SuperInit/EarlyAssignments.out @@ -16,7 +16,7 @@ EarlyAssignments.java:129:29: compiler.err.cant.ref.before.ctor.called: x EarlyAssignments.java:134:22: compiler.err.cant.ref.before.ctor.called: x EarlyAssignments.java:139:28: compiler.err.cant.ref.before.ctor.called: x EarlyAssignments.java:157:13: compiler.err.cant.assign.val.to.var: final, x -EarlyAssignments.java:168:13: compiler.err.cant.ref.before.ctor.called: this +EarlyAssignments.java:168:18: compiler.err.cant.ref.before.ctor.called: EarlyAssignments.Inner8.Inner8a() - compiler.note.preview.filename: EarlyAssignments.java, DEFAULT - compiler.note.preview.recompile 19 errors diff --git a/test/langtools/tools/javac/SuperInit/EarlyIndirectOuterCapture.java b/test/langtools/tools/javac/SuperInit/EarlyIndirectOuterCapture.java index 9336c4dc183..475915dddca 100644 --- a/test/langtools/tools/javac/SuperInit/EarlyIndirectOuterCapture.java +++ b/test/langtools/tools/javac/SuperInit/EarlyIndirectOuterCapture.java @@ -2,7 +2,7 @@ * @test /nodynamiccopyright/ * @bug 8334248 * @summary Invalid error for early construction local class constructor method reference - * @compile/fail/ref=EarlyIndirectOuterCapture.out -XDrawDiagnostics EarlyIndirectOuterCapture.java + * @compile EarlyIndirectOuterCapture.java */ public class EarlyIndirectOuterCapture { @@ -18,7 +18,7 @@ class InnerSuperclass { } static class InnerOuter extends EarlyIndirectOuterCapture { // accessible class InnerInnerOuter extends EarlyIndirectOuterCapture { // not accessible InnerInnerOuter() { - super(/* which enclosing instance here ? */new InnerSuperclass() { }); + super(new InnerSuperclass() { }); // should this be accepted?, InnerSuperclass is not an inner class of InnerInnerOuter } InnerInnerOuter(boolean b) { diff --git a/test/langtools/tools/javac/SuperInit/EarlyIndirectOuterCapture.out b/test/langtools/tools/javac/SuperInit/EarlyIndirectOuterCapture.out deleted file mode 100644 index 7b96671a2bd..00000000000 --- a/test/langtools/tools/javac/SuperInit/EarlyIndirectOuterCapture.out +++ /dev/null @@ -1,2 +0,0 @@ -EarlyIndirectOuterCapture.java:21:60: compiler.err.cant.ref.before.ctor.called: this -1 error diff --git a/test/langtools/tools/javac/SuperInit/EarlyLocalClass.out b/test/langtools/tools/javac/SuperInit/EarlyLocalClass.out index ee01f9c403d..6ca47a65241 100644 --- a/test/langtools/tools/javac/SuperInit/EarlyLocalClass.out +++ b/test/langtools/tools/javac/SuperInit/EarlyLocalClass.out @@ -1,4 +1,4 @@ -EarlyLocalClass.java:12:32: compiler.err.cant.ref.before.ctor.called: this +EarlyLocalClass.java:12:37: compiler.err.cant.ref.before.ctor.called: hashCode() - compiler.note.preview.filename: EarlyLocalClass.java, DEFAULT - compiler.note.preview.recompile 1 error diff --git a/test/langtools/tools/javac/SuperInit/SuperInitFails.java b/test/langtools/tools/javac/SuperInit/SuperInitFails.java index feb5b81c1b0..864ca59c115 100644 --- a/test/langtools/tools/javac/SuperInit/SuperInitFails.java +++ b/test/langtools/tools/javac/SuperInit/SuperInitFails.java @@ -152,7 +152,7 @@ public SuperInitFails(float[][] x) { } public SuperInitFails(int[][] z) { - super((Runnable)() -> x); // this should FAIL + super((Runnable)() -> System.err.println(x)); // this should FAIL } public SuperInitFails(long[][] z) { diff --git a/test/langtools/tools/javac/SuperInit/SuperInitFails.out b/test/langtools/tools/javac/SuperInit/SuperInitFails.out index 8ee4cfafe5b..5fca1d0db83 100644 --- a/test/langtools/tools/javac/SuperInit/SuperInitFails.out +++ b/test/langtools/tools/javac/SuperInit/SuperInitFails.out @@ -8,15 +8,16 @@ SuperInitFails.java:104:14: compiler.err.cant.ref.before.ctor.called: this SuperInitFails.java:108:20: compiler.err.not.encl.class: java.lang.Object SuperInitFails.java:112:23: compiler.err.cant.ref.before.ctor.called: spliterator() SuperInitFails.java:119:22: compiler.err.call.must.only.appear.in.ctor -SuperInitFails.java:125:9: compiler.err.cant.ref.before.ctor.called: this +SuperInitFails.java:125:9: compiler.err.cant.ref.before.ctor.called: SuperInitFails.Inner1() SuperInitFails.java:133:9: compiler.err.non.canonical.constructor.invoke.another.constructor: SuperInitFails.Record1 SuperInitFails.java:138:9: compiler.err.non.canonical.constructor.invoke.another.constructor: SuperInitFails.Record2 -SuperInitFails.java:155:31: compiler.err.cant.ref.before.ctor.called: x -SuperInitFails.java:159:15: compiler.err.cant.ref.before.ctor.called: this +SuperInitFails.java:155:50: compiler.err.cant.ref.before.ctor.called: x +SuperInitFails.java:159:15: compiler.err.cant.ref.before.ctor.called: SuperInitFails.Inner1() SuperInitFails.java:168:13: compiler.err.cant.ref.before.ctor.called: x SuperInitFails.java:172:17: compiler.err.cant.ref.before.ctor.called: x SuperInitFails.java:176:24: compiler.err.cant.ref.before.ctor.called: x SuperInitFails.java:180:18: compiler.err.cant.ref.before.ctor.called: x +SuperInitFails.java:186:32: compiler.err.cant.ref.before.ctor.called: x SuperInitFails.java:195:25: compiler.err.return.before.superclass.initialized SuperInitFails.java:200:33: compiler.err.ctor.calls.not.allowed.here SuperInitFails.java:205:29: compiler.err.redundant.superclass.init diff --git a/test/langtools/tools/javac/SuperInit/ValueClassSuperInitFails.out b/test/langtools/tools/javac/SuperInit/ValueClassSuperInitFails.out index 914a97b63aa..660cd827b62 100644 --- a/test/langtools/tools/javac/SuperInit/ValueClassSuperInitFails.out +++ b/test/langtools/tools/javac/SuperInit/ValueClassSuperInitFails.out @@ -1,18 +1,19 @@ ValueClassSuperInitFails.java:67:9: compiler.err.cant.ref.before.ctor.called: hashCode() -ValueClassSuperInitFails.java:72:9: compiler.err.cant.ref.before.ctor.called: this -ValueClassSuperInitFails.java:77:9: compiler.err.cant.ref.before.ctor.called: super -ValueClassSuperInitFails.java:82:33: compiler.err.cant.ref.before.ctor.called: this -ValueClassSuperInitFails.java:87:33: compiler.err.cant.ref.before.ctor.called: super +ValueClassSuperInitFails.java:72:13: compiler.err.cant.ref.before.ctor.called: hashCode() +ValueClassSuperInitFails.java:77:14: compiler.err.cant.ref.before.ctor.called: hashCode() +ValueClassSuperInitFails.java:82:38: compiler.err.cant.ref.before.ctor.called: hashCode() +ValueClassSuperInitFails.java:87:39: compiler.err.cant.ref.before.ctor.called: hashCode() ValueClassSuperInitFails.java:109:33: compiler.err.cant.ref.before.ctor.called: this ValueClassSuperInitFails.java:114:14: compiler.err.cant.ref.before.ctor.called: this ValueClassSuperInitFails.java:118:20: compiler.err.not.encl.class: java.lang.Object -ValueClassSuperInitFails.java:122:17: compiler.err.cant.ref.before.ctor.called: super +ValueClassSuperInitFails.java:122:23: compiler.err.cant.ref.before.ctor.called: spliterator() ValueClassSuperInitFails.java:129:22: compiler.err.call.must.only.appear.in.ctor -ValueClassSuperInitFails.java:135:9: compiler.err.cant.ref.before.ctor.called: this +ValueClassSuperInitFails.java:135:9: compiler.err.cant.ref.before.ctor.called: ValueClassSuperInitFails.Inner1() ValueClassSuperInitFails.java:143:9: compiler.err.non.canonical.constructor.invoke.another.constructor: ValueClassSuperInitFails.Record1 ValueClassSuperInitFails.java:148:9: compiler.err.non.canonical.constructor.invoke.another.constructor: ValueClassSuperInitFails.Record2 -ValueClassSuperInitFails.java:161:41: compiler.err.cant.ref.before.ctor.called: this -ValueClassSuperInitFails.java:179:15: compiler.err.cant.ref.before.ctor.called: this +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.Inner1() 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 @@ -24,4 +25,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 -24 errors +25 errors diff --git a/test/langtools/tools/javac/cantReferenceBeforeCtor/CantReferenceBeforeConstructorTest.out b/test/langtools/tools/javac/cantReferenceBeforeCtor/CantReferenceBeforeConstructorTest.out index 78b0b35e373..e7352bb162f 100644 --- a/test/langtools/tools/javac/cantReferenceBeforeCtor/CantReferenceBeforeConstructorTest.out +++ b/test/langtools/tools/javac/cantReferenceBeforeCtor/CantReferenceBeforeConstructorTest.out @@ -1,2 +1,2 @@ -CantReferenceBeforeConstructorTest.java:30:13: compiler.err.cant.ref.before.ctor.called: this +CantReferenceBeforeConstructorTest.java:30:17: compiler.err.cant.ref.before.ctor.called: CantReferenceBeforeConstructorTest.BB.CC() 1 error From 808fbef0b2a85fccb791595eb277674ff72aae72 Mon Sep 17 00:00:00 2001 From: Vicente Romero Date: Fri, 15 Aug 2025 10:58:08 -0400 Subject: [PATCH 03/10] additional changes --- .../com/sun/tools/javac/comp/Attr.java | 46 ++++++++++++++++--- .../com/sun/tools/javac/comp/Resolve.java | 3 -- .../SuperInit/EarlyAssignmentNoPreview1.java | 2 +- .../SuperInit/EarlyAssignmentNoPreview2.java | 2 +- .../SuperInit/EarlyAssignmentNoPreview3.java | 2 +- .../javac/SuperInit/EarlyAssignments.out | 3 +- .../diags/examples/CantRefBeforeConstr.java | 3 +- .../lambda/MethodReferenceNoThisTest.out | 2 +- .../ValueObjectCompilationTests.java | 4 +- 9 files changed, 49 insertions(+), 18 deletions(-) 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 35a65872e3e..7b97f60ebb1 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 @@ -124,6 +124,7 @@ public class Attr extends JCTree.Visitor { final ArgumentAttr argumentAttr; final MatchBindingsComputer matchBindingsComputer; final AttrRecover attrRecover; + final LocalProxyVarsGen localProxyVarsGen; public static Attr instance(Context context) { Attr instance = context.get(attrKey); @@ -163,6 +164,7 @@ protected Attr(Context context) { argumentAttr = ArgumentAttr.instance(context); matchBindingsComputer = MatchBindingsComputer.instance(context); attrRecover = AttrRecover.instance(context); + localProxyVarsGen = LocalProxyVarsGen.instance(context); Options options = Options.instance(context); @@ -1357,9 +1359,34 @@ public void visitNewClass(JCNewClass tree) { } } + @Override + public void visitReference(JCMemberReference tree) { + super.visitReference(tree); + if (tree.getMode() == JCMemberReference.ReferenceMode.NEW) { + if (tree.expr.type.tsym.isEnclosedBy(env.enclClass.sym) && !tree.expr.type.tsym.isStatic() && !tree.expr.type.tsym.isDirectlyOrIndirectlyLocal()) { + log.error(tree, Errors.CantRefBeforeCtorCalled(tree.expr.type.getEnclosingType().tsym)); + } + /*Type enclosingType = tree.expr.type.getEnclosingType(); + if (enclosingType != null && enclosingType.hasTag(CLASS)) {*/ + + // Check for the existence of an appropriate outer instance + //rs.resolveImplicitThis(that.pos(), env, exprType); + /*if (tree.expr.type.tsym.isEnclosedBy(env.enclClass.sym) && !tree.type.tsym.isStatic() && !tree.type.tsym.isDirectlyOrIndirectlyLocal()) { + log.error(tree, Errors.CantRefBeforeCtorCalled(tree.sym)); + }*/ + //} + } + } + @Override public void visitAssign(JCAssign tree) { super.visitAssign(tree); + Symbol sym = TreeInfo.symbolFor(tree.lhs); + if (sym != null && + (sym.flags() & HASINIT) != 0 && + sym.owner == localEnv.enclClass.sym) { + log.error(tree.lhs, Errors.CantAssignInitializedBeforeCtorCalled(sym)); + } if (tree.rhs.type.constValue() == null) { analyzeTree(tree.rhs); } @@ -1382,9 +1409,6 @@ JCTree filter(JCTree tree) { } void analyzeTree(JCTree jcTree) { - if (jcTree.toString().equals("(int)e.size")) { - //System.err.println("stop here Attr"); - } jcTree = filter(jcTree); java.util.List symbols = TreeInfo.symbolsFor(jcTree); for (TreeInfo.SymAndTree symAndTree : symbols) { @@ -1392,13 +1416,13 @@ void analyzeTree(JCTree jcTree) { JCTree tree = filter(symAndTree.tree()); if (!sym.isStatic() && !isMethodParam(tree)) { if (sym.name == names._this || sym.name == names._super) { - if (TreeInfo.isExplicitThisReference(types, (ClassType)env.enclClass.sym.type, tree)) { + if (TreeInfo.isExplicitThisReference(types, (ClassType)localEnv.enclClass.sym.type, tree)) { log.error(tree, Errors.CantRefBeforeCtorCalled(sym)); } } else { if (sym != null && !sym.owner.isAnonymous() && - sym.owner != env.enclClass.sym && + sym.owner != localEnv.enclClass.sym && sym.kind == VAR && sym.owner.kind == TYP) { //Assert.check(tree.hasTag(IDENT) || tree.hasTag(SELECT), "unexpected tree " + tree + " with tag " + tree.getTag()); @@ -1407,7 +1431,7 @@ void analyzeTree(JCTree jcTree) { throw new AssertionError("unexpected tree " + tree + " with tag " + tree.getTag()); } Symbol owner = tree.hasTag(IDENT) ? sym.owner : ((JCFieldAccess)tree).selected.type.tsym; - if (env.enclClass.sym.isSubClass(owner, types) && sym.isInheritedIn(env.enclClass.sym, types)) { + if (localEnv.enclClass.sym.isSubClass(owner, types) && sym.isInheritedIn(localEnv.enclClass.sym, types)) { log.error(tree, Errors.CantRefBeforeCtorCalled(sym)); } //if () { //env.enclClass.sym.isEnclosedBy((ClassSymbol) sym.owner) @@ -1415,6 +1439,11 @@ void analyzeTree(JCTree jcTree) { //} else { // log.error(tree, Errors.CantRefBeforeCtorCalled(sym)); //} + } else { + if ((sym.isFinal() || sym.isStrict()) && + sym.kind == VAR && + sym.owner.kind == TYP) + localProxyVarsGen.addStrictFieldReadInPrologue(localEnv.enclMethod, sym); } } } @@ -1537,6 +1566,11 @@ public void visitVarDef(JCVariableDecl tree) { //fixup local variable type v.type = chk.checkLocalVarType(tree, tree.init.type, tree.name); } + // don't analyze if we are already inside a constructor's prologue + if (!previousCtorPrologue && initEnv.info.ctorPrologue) { + CtorPrologueVisitor ctorPrologueVisitor = new CtorPrologueVisitor(initEnv); + ctorPrologueVisitor.scan(tree); + } } finally { initEnv.info.ctorPrologue = previousCtorPrologue; } diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java index be4381beb4d..eeb09e9a851 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java @@ -1463,9 +1463,6 @@ Symbol findField(Env env, Type site, Name name, TypeSymbol c) { - if (env.tree.toString().contains("EventRequestManagerImpl.this.vm") && name.toString().equals("vm")) { - //System.err.println("stop here"); - } while (c.type.hasTag(TYPEVAR)) c = c.type.getUpperBound().tsym; Symbol bestSoFar = varNotFound; diff --git a/test/langtools/tools/javac/SuperInit/EarlyAssignmentNoPreview1.java b/test/langtools/tools/javac/SuperInit/EarlyAssignmentNoPreview1.java index abb6bacbc8f..0d7938d7216 100644 --- a/test/langtools/tools/javac/SuperInit/EarlyAssignmentNoPreview1.java +++ b/test/langtools/tools/javac/SuperInit/EarlyAssignmentNoPreview1.java @@ -2,7 +2,7 @@ * @test /nodynamiccopyright/ * @bug 8334258 * @summary Disallow early assignment if FLEXIBLE_CONSTRUCTORS preview feature is not enabled - * @compile/fail/ref=EarlyAssignmentNoPreview1.out -XDrawDiagnostics EarlyAssignmentNoPreview1.java + * @compile/fail/ref=EarlyAssignmentNoPreview1.out --release 24 -XDrawDiagnostics EarlyAssignmentNoPreview1.java */ public class EarlyAssignmentNoPreview1 { diff --git a/test/langtools/tools/javac/SuperInit/EarlyAssignmentNoPreview2.java b/test/langtools/tools/javac/SuperInit/EarlyAssignmentNoPreview2.java index 3c33734f42a..64332244e01 100644 --- a/test/langtools/tools/javac/SuperInit/EarlyAssignmentNoPreview2.java +++ b/test/langtools/tools/javac/SuperInit/EarlyAssignmentNoPreview2.java @@ -2,7 +2,7 @@ * @test /nodynamiccopyright/ * @bug 8334258 * @summary Disallow early assignment if FLEXIBLE_CONSTRUCTORS preview feature is not enabled - * @compile/fail/ref=EarlyAssignmentNoPreview2.out -XDrawDiagnostics EarlyAssignmentNoPreview2.java + * @compile/fail/ref=EarlyAssignmentNoPreview2.out --release 24 -XDrawDiagnostics EarlyAssignmentNoPreview2.java */ public class EarlyAssignmentNoPreview2 { diff --git a/test/langtools/tools/javac/SuperInit/EarlyAssignmentNoPreview3.java b/test/langtools/tools/javac/SuperInit/EarlyAssignmentNoPreview3.java index f6269f2cb1f..e021d80e6c1 100644 --- a/test/langtools/tools/javac/SuperInit/EarlyAssignmentNoPreview3.java +++ b/test/langtools/tools/javac/SuperInit/EarlyAssignmentNoPreview3.java @@ -2,7 +2,7 @@ * @test /nodynamiccopyright/ * @bug 8334258 * @summary Disallow early assignment if FLEXIBLE_CONSTRUCTORS preview feature is not enabled - * @compile/fail/ref=EarlyAssignmentNoPreview3.out -XDrawDiagnostics EarlyAssignmentNoPreview3.java + * @compile/fail/ref=EarlyAssignmentNoPreview3.out --release 24 -XDrawDiagnostics EarlyAssignmentNoPreview3.java */ public class EarlyAssignmentNoPreview3 { diff --git a/test/langtools/tools/javac/SuperInit/EarlyAssignments.out b/test/langtools/tools/javac/SuperInit/EarlyAssignments.out index 29e4989384e..586f2486dde 100644 --- a/test/langtools/tools/javac/SuperInit/EarlyAssignments.out +++ b/test/langtools/tools/javac/SuperInit/EarlyAssignments.out @@ -15,8 +15,9 @@ EarlyAssignments.java:124:22: compiler.err.cant.ref.before.ctor.called: x EarlyAssignments.java:129:29: compiler.err.cant.ref.before.ctor.called: x EarlyAssignments.java:134:22: compiler.err.cant.ref.before.ctor.called: x EarlyAssignments.java:139:28: compiler.err.cant.ref.before.ctor.called: x +EarlyAssignments.java:148:13: compiler.err.cant.assign.initialized.before.ctor.called: x EarlyAssignments.java:157:13: compiler.err.cant.assign.val.to.var: final, x EarlyAssignments.java:168:18: compiler.err.cant.ref.before.ctor.called: EarlyAssignments.Inner8.Inner8a() - compiler.note.preview.filename: EarlyAssignments.java, DEFAULT - compiler.note.preview.recompile -19 errors +20 errors diff --git a/test/langtools/tools/javac/diags/examples/CantRefBeforeConstr.java b/test/langtools/tools/javac/diags/examples/CantRefBeforeConstr.java index cc83c86f80d..45728a3c86b 100644 --- a/test/langtools/tools/javac/diags/examples/CantRefBeforeConstr.java +++ b/test/langtools/tools/javac/diags/examples/CantRefBeforeConstr.java @@ -24,12 +24,11 @@ // key: compiler.err.cant.ref.before.ctor.called class Base { + int i; Base(int i) { } } class CantRefBeforeConstr extends Base { - int i; - CantRefBeforeConstr() { super(i); } diff --git a/test/langtools/tools/javac/lambda/MethodReferenceNoThisTest.out b/test/langtools/tools/javac/lambda/MethodReferenceNoThisTest.out index a411c340484..f5a535b73ff 100644 --- a/test/langtools/tools/javac/lambda/MethodReferenceNoThisTest.out +++ b/test/langtools/tools/javac/lambda/MethodReferenceNoThisTest.out @@ -1,2 +1,2 @@ -MethodReferenceNoThisTest.java:22:15: compiler.err.cant.ref.before.ctor.called: this +MethodReferenceNoThisTest.java:22:15: compiler.err.cant.ref.before.ctor.called: MethodReferenceNoThisTest 1 error diff --git a/test/langtools/tools/javac/valhalla/value-objects/ValueObjectCompilationTests.java b/test/langtools/tools/javac/valhalla/value-objects/ValueObjectCompilationTests.java index 1b8a03f5494..3e89639569e 100644 --- a/test/langtools/tools/javac/valhalla/value-objects/ValueObjectCompilationTests.java +++ b/test/langtools/tools/javac/valhalla/value-objects/ValueObjectCompilationTests.java @@ -919,11 +919,11 @@ value class V { } """ ); - assertOK( + assertFail("compiler.err.cant.ref.before.ctor.called", """ value class Test { Test t = null; - Runnable r = () -> { System.err.println(t); }; // compiler will generate a local proxy for `t` + Runnable r = () -> { System.err.println(t); }; // cant reference `t` from a lambda expression in the prologue } """ ); From 993b6577303d9c6f6afffb0d7776a46c6de1e2cd Mon Sep 17 00:00:00 2001 From: Vicente Romero Date: Fri, 15 Aug 2025 18:05:03 -0400 Subject: [PATCH 04/10] additional changes --- .../com/sun/tools/javac/comp/Attr.java | 48 ++---------------- .../com/sun/tools/javac/comp/Resolve.java | 4 -- .../maskSyntheticModifier/Foo.class | Bin 0 -> 667 bytes test/jdk/java/lang/Class/EnumPoseur.class | Bin 0 -> 256 bytes .../java/lang/Class/forName/classes/0.class | Bin 0 -> 408 bytes .../java/lang/Class/forName/classes/3.class | Bin 0 -> 408 bytes .../java/lang/Class/forName/classes/Z.class | Bin 0 -> 408 bytes .../lang/Class/forName/classes/comma.class | Bin 0 -> 408 bytes .../lang/Class/forName/classes/hyphen.class | Bin 0 -> 408 bytes .../Class/forName/classes/left-square.class | Bin 0 -> 408 bytes .../lang/Class/forName/classes/period.class | Bin 0 -> 408 bytes .../lang/Class/forName/classes/plus.class | Bin 0 -> 408 bytes .../Class/forName/classes/right-square.class | Bin 0 -> 408 bytes 13 files changed, 5 insertions(+), 47 deletions(-) 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 7b97f60ebb1..20cf6416104 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 @@ -329,7 +329,7 @@ void checkAssignable(DiagnosticPosition pos, VarSymbol v, JCTree base, Env prologueCode = new ListBuffer<>(); for (JCTree stat : tree.body.stats) { prologueCode.add(stat); + // gather all the stats in the body until the super or this invocation is found, including it if (stat instanceof JCExpressionStatement expStmt && expStmt.expr instanceof JCMethodInvocation mi && TreeInfo.isConstructorCall(mi)) { @@ -1328,7 +1329,7 @@ public void visitApply(JCMethodInvocation tree) { log.error(tree.meth, Errors.CantRefBeforeCtorCalled(msym)); } } else if (msym.isMemberOf(env.enclClass.sym, types)){ - // where we are dealing with an inherited method, probably an error too + // here we are dealing with an inherited method, probably an error too if (tree.meth instanceof JCFieldAccess fa) { if (TreeInfo.isExplicitThisReference(types, (ClassType)env.enclClass.sym.type, fa.selected)) { log.error(tree.meth, Errors.CantRefBeforeCtorCalled(msym)); @@ -1366,27 +1367,18 @@ public void visitReference(JCMemberReference tree) { if (tree.expr.type.tsym.isEnclosedBy(env.enclClass.sym) && !tree.expr.type.tsym.isStatic() && !tree.expr.type.tsym.isDirectlyOrIndirectlyLocal()) { log.error(tree, Errors.CantRefBeforeCtorCalled(tree.expr.type.getEnclosingType().tsym)); } - /*Type enclosingType = tree.expr.type.getEnclosingType(); - if (enclosingType != null && enclosingType.hasTag(CLASS)) {*/ - - // Check for the existence of an appropriate outer instance - //rs.resolveImplicitThis(that.pos(), env, exprType); - /*if (tree.expr.type.tsym.isEnclosedBy(env.enclClass.sym) && !tree.type.tsym.isStatic() && !tree.type.tsym.isDirectlyOrIndirectlyLocal()) { - log.error(tree, Errors.CantRefBeforeCtorCalled(tree.sym)); - }*/ - //} } } @Override public void visitAssign(JCAssign tree) { super.visitAssign(tree); - Symbol sym = TreeInfo.symbolFor(tree.lhs); + /*Symbol sym = TreeInfo.symbolFor(tree.lhs); if (sym != null && (sym.flags() & HASINIT) != 0 && sym.owner == localEnv.enclClass.sym) { log.error(tree.lhs, Errors.CantAssignInitializedBeforeCtorCalled(sym)); - } + }*/ if (tree.rhs.type.constValue() == null) { analyzeTree(tree.rhs); } @@ -1425,20 +1417,13 @@ void analyzeTree(JCTree jcTree) { sym.owner != localEnv.enclClass.sym && sym.kind == VAR && sym.owner.kind == TYP) { - //Assert.check(tree.hasTag(IDENT) || tree.hasTag(SELECT), "unexpected tree " + tree + " with tag " + tree.getTag()); if (!tree.hasTag(IDENT) && !tree.hasTag(SELECT)) { - //tree = filter(tree); throw new AssertionError("unexpected tree " + tree + " with tag " + tree.getTag()); } Symbol owner = tree.hasTag(IDENT) ? sym.owner : ((JCFieldAccess)tree).selected.type.tsym; if (localEnv.enclClass.sym.isSubClass(owner, types) && sym.isInheritedIn(localEnv.enclClass.sym, types)) { log.error(tree, Errors.CantRefBeforeCtorCalled(sym)); } - //if () { //env.enclClass.sym.isEnclosedBy((ClassSymbol) sym.owner) - // do nothing - //} else { - // log.error(tree, Errors.CantRefBeforeCtorCalled(sym)); - //} } else { if ((sym.isFinal() || sym.isStrict()) && sym.kind == VAR && @@ -1469,29 +1454,6 @@ boolean isMethodParam(JCTree tree) { } return false; } -/* - class FindEnclosingSelect extends TreeScanner { - JCTree treeToLookFor; - JCFieldAccess enclosingSelect = null; - - public JCFieldAccess scan(JCTree treeToLookFor, JCTree tree) { - this.treeToLookFor = treeToLookFor; - super.scan(tree); - return enclosingSelect; - } - - @Override - public void visitSelect(JCFieldAccess tree) { - if (tree.selected == treeToLookFor) { - enclosingSelect = tree; - // this select could be part of an enclosing select - treeToLookFor = tree; - } else { - scan(tree.selected); - } - } - } - */ } public void visitVarDef(JCVariableDecl tree) { diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java index eeb09e9a851..acb029114a4 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java @@ -2044,8 +2044,6 @@ Symbol findFun(Env env, Name name, (sym.flags() & STATIC) == 0) { if (staticOnly) return new StaticError(sym); - /*if (env1.info.ctorPrologue && env1 == env) - return new RefBeforeCtorCalledError(sym);*/ } return sym; } else { @@ -3887,8 +3885,6 @@ Symbol resolveSelf(DiagnosticPosition pos, //this might be a default super call if one of the superinterfaces is 'c' for (Type t : pruneInterfaces(env.enclClass.type)) { if (t.tsym == c) { - /*if (env.info.ctorPrologue) - log.error(pos, Errors.CantRefBeforeCtorCalled(name));*/ env.info.defaultSuperCallSite = t; return new VarSymbol(0, names._super, types.asSuper(env.enclClass.type, c), env.enclClass.sym); diff --git a/test/jdk/java/io/Serializable/maskSyntheticModifier/Foo.class b/test/jdk/java/io/Serializable/maskSyntheticModifier/Foo.class index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..1777af8b136a3a0f7a1622fa0482c100b5b2bf0e 100644 GIT binary patch literal 667 zcmZuv-%k@k5dMai?)5lnsYL{oUlwR<(k8yv@Pafksr8|TgvaZ#981cr*=~*c5Bchk zM2IH(Xu=;wn7!7tF+SYx%{MdO%r~<)w?BRXXrS)nAyx&}1lE1b;gOFF9{X6pMjk#k zJ#6`WZwu@QJQ1i6R-!>T99AyEcVT4^CUNCuVr481VX5Q5rURRYE~rJw_dX={Tv`;WNDtsN7xhx$|!3LTZm?&z{F&6}`4U?exLK-jI$F!robN!+TP>|vR(^-o`2ZQFX3oF2W8+xf0U&-MxjM*qxXZ24;LRkLappLQ4t6Kme;Lmd{^IhP*gEtMQgY6Rkwb*vZ zdi@HyuMmGwD0$b&pL~P(lp>uk>?YjjbCF*Nm?p~vYfRxe$(-(pp0UpnmFm}^&z+yh foIL%G>=ovJb2d0vdp1tEx#()~n-Fw#t5n(2SJ5?u5H`cdMY zZaRxMXYM<^H^;x<1Ary2GK9EHkS8bv;zw=tuoAeQS6^~3%dIqRSr1m5_Tlw*BM?3H zpGu&pv{7%aYm{BfX3He4b!+6{EIFKeHLH7PKh%r%?c&+E?!DhBXBU1lC;4Q82qUWJ yu0Vd?>|;z3@Q?lo5`ET~uNhOHCwKQZKM>z1Az{rZ04b#m7o>n3kUfnt;f;U7#xWcK literal 0 HcmV?d00001 diff --git a/test/jdk/java/lang/Class/forName/classes/0.class b/test/jdk/java/lang/Class/forName/classes/0.class index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..b5b6c8f2b56dc600192faf40bd74200dfdc01889 100644 GIT binary patch literal 408 zcmZutyH3ME5S&dMzc3^uI6PBOAQ_6-)Il^zh#~?cBN{3@IYk%wfs75}v!DQpf)C)M z5PMD$MdFIxz1i8>x%>J3`UY@{fejsP3mt5l=-TLE%YbX3Ptea~Cd+d|(>uN=XczfZ z5ZYsziR&tjMR6C!2_sq>$&AqV9>(+NIr5VzoB3f`$ZR%JgLar##Y9|6Mb?9%A~`T% z8rXKQgI$7iC6Xi$Uh*QD4h`%%*vA2Z0zzl0c@xjYq+Ef**QZjXY%#C6;Vulw+`r}R zC3_H2IwJIHja8UnJStMc)?M#E=Qu=*KS!Mgm=2Sp#kT=x;@mp<1if*=Z{(;iK&Gt0 e;aX9T>QTUYN2A;PfVQOD+(NCYbl16VVB-%`olool literal 0 HcmV?d00001 diff --git a/test/jdk/java/lang/Class/forName/classes/3.class b/test/jdk/java/lang/Class/forName/classes/3.class index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..4d183b07c2c1c71e7ab4719eac8371a2e343298f 100644 GIT binary patch literal 408 zcmZutyH3ME5S&dMzc3^uI6PBOAQ_5S$Yl@>5~7Fz$%ux^PEOH9ejsCm_$(+uqTmDg zD8!yqM3J~+cW-ufcJ6+DzrF#SVqil@+d>DMCb~9y*fQW6=o9oanaT2;(DaV)3ED+I z6@>O!X5zX^V^Q2ial(j}MlvJxy@&BUdXD@g%4U987BZWS)Sw;aRWT8lQjzsws7MYB zm|mGRT!|#fgO|KWrb7dJ4)$?Cpn%X>YTm?iF)3G|@b#$_DO=1dZnz5rGWTzJ zd&wR|l#U3!T4NO^7>|mSuyxn_&p8g!;?Gg10j9&`Xz^{pnK-vjK0$9>@EbYm3y>*m faJW{~qk0su-qGkbKcFq?Hn&i#D&2Li8`$^*ThmYV literal 0 HcmV?d00001 diff --git a/test/jdk/java/lang/Class/forName/classes/Z.class b/test/jdk/java/lang/Class/forName/classes/Z.class index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..cedf4a38923ee73b88f8fe1c3bc11d171aad8731 100644 GIT binary patch literal 408 zcmZutO-sW-5Pj38`7+wtn)+F=2O)ZB@LcgCh=-y=#6vwL?NYYnLt>)%v-F_g!5`p{ z5@*vxDY%E3**9eFp-c%~?_o3#pF=+m)0rO>xlCt6HE0J}nNP%}RAhZTP$UNi zOat2vcCbruu0$MXhc8(kPX`9}9PHzOKx0B{sd*F4#iUq)g4d@)By2G&x#2Dh$jrax z?FD-fVKO9iDvec`U_2^P%+_7+Kj-M9!Jnf}4NQm0(c)W=GjVR5e1hJ%;5TyA7a&vC f;Bc*|N7X1`y`$Eye?VK(ZEm4bRl4h3*Rb&inB!0| literal 0 HcmV?d00001 diff --git a/test/jdk/java/lang/Class/forName/classes/comma.class b/test/jdk/java/lang/Class/forName/classes/comma.class index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..7d21d7106f724bbcde041431b9669ed5e8856287 100644 GIT binary patch literal 408 zcmZutO-sW-5Pj38`7+wtn)=y;2O&ym@LcgCh=-y=#EYk-UCNexNK6!emL3#5_yhb= z;%s^-1@|yB`{vD?xBK(^^$p+@0~|HVeYCklAdc2JJAfiixt-IcT&T)tqe~vm0FdZgGi*EzY#JP3y33}s#-^fv4fJ|9~ e!?mIw)uVv*jz+in0c}aQxrJI)>8^9#z{Vd&RZrjm literal 0 HcmV?d00001 diff --git a/test/jdk/java/lang/Class/forName/classes/hyphen.class b/test/jdk/java/lang/Class/forName/classes/hyphen.class index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..9ca321382fb1243663ebc139a557e1c795e5dd37 100644 GIT binary patch literal 408 zcmZutO-sW-5Pj38`7+wtn)=y;2O$b+@LcgCh=-y=#EYk-UCNexNK6!emL3#5_yhb= z;%s^-1@|yB`{vD?xBK(^^$p+@0~|HVeYCklAdc2JJAfiixt-IcT&T)tqe~vm0FdZgGi*EzY#JP3y33}s#-^fv4fJ|9~ e!?mIw)uVv*jz+in0c}aQxrJI)>8^9#z{Vd*XHVk* literal 0 HcmV?d00001 diff --git a/test/jdk/java/lang/Class/forName/classes/left-square.class b/test/jdk/java/lang/Class/forName/classes/left-square.class index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..8d5009df65ee43eedb4b0686ee374b45de6eb1f5 100644 GIT binary patch literal 408 zcmZutyH3ME5S(=!+cAcO1czq|3M4}ji#mt~2~k9VWJKf2PEOH9eniFw@mWxSM8OB} zQHVXKh$3;t?%wR|?A-nQetiQt$H0bxb_*SBTj<*8VaJ4PqE9d`WG2f?Lc=?KB zSSEHI>|vka+=wK}!|df$6X~w)i&SOq`o%pP)A`_>CNmCCHQw fI9x00Nj(a*-l26HAJA8Hn_H+=mF_0j8n*rb)}v5u literal 0 HcmV?d00001 diff --git a/test/jdk/java/lang/Class/forName/classes/period.class b/test/jdk/java/lang/Class/forName/classes/period.class index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..2581aab2c6da4282349e48654c2a07dbdd2ccfb5 100644 GIT binary patch literal 408 zcmZutyH3ME5S(=!zc3^uI6PBOAQ=i<)Il^zh#~?cBN{3@IYk%wfs75}v!DQpf)C)M z5PMD$MdFIxz1i8>x%>J3`UY@{p#uXQ8(nN#=sD dTr28PGYZ)6(0Z*8=u5i8Ei|f1cb#hu8-GlBPv!ss literal 0 HcmV?d00001 diff --git a/test/jdk/java/lang/Class/forName/classes/plus.class b/test/jdk/java/lang/Class/forName/classes/plus.class index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..32037d725d16236f8b10542526d9080f3dfc3c59 100644 GIT binary patch literal 408 zcmZutO-sW-5Pj38`7+wtn)=y;2O%10@LcgCh=-y=#EYk-UCNexNK6!emL3#5_yhb= z;%s^-1@|yB`{vD?xBK(^^$p+@0~|HVeYCklAdc2JJAfiixt-IcT&T)tqe~vm0FdZgGi*EzY#JP3y33}s#-^fv4fJ|9~ e!?mIw)uVv*jz+in0c}aQxrJI)>8^9#z{Vd#Lr>iR literal 0 HcmV?d00001 diff --git a/test/jdk/java/lang/Class/forName/classes/right-square.class b/test/jdk/java/lang/Class/forName/classes/right-square.class index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0b61551e9025c23664e5a714d35927d1f73d17c7 100644 GIT binary patch literal 408 zcmZutyH3ME5S&dMzc3^uI6PBOAQ_5S)Il^zh#~?cBO2twPEOH9ejsCm_$(+uqTmDg zD8!yqM3J~+cW-ufcJ6+DzrF#SVqil@+d>DMCb~9y*fQW6=o9oanaT2;(DaV)3ED+I z6@>O!X5zX^V^Q2ial(j}MlvJxy@&BUdXD@g%4U907BZWS)Sw;YRWT8lQjzs=s7MYB zm|mGRT!|#f!|mSuyxn_&p8g!;?Gg10j9&`Xz^{pnK-vjK0$9>@EbYm3y>*m faJW{~qk0su-qGkbKcFq?Hn&i#D&2Li8`$^*+{aLJ literal 0 HcmV?d00001 From fd2cd236190b92156c20779dba329ab5b2b65bfa Mon Sep 17 00:00:00 2001 From: Vicente Romero Date: Fri, 15 Aug 2025 18:08:34 -0400 Subject: [PATCH 05/10] restoring removed class files --- .../lang/Class/forName/classes/semicolon.class | Bin 0 -> 408 bytes test/jdk/sun/misc/Hello.class | Bin 0 -> 401 bytes .../sun/security/tools/jarsigner/oldsig/A.class | Bin 0 -> 176 bytes 3 files changed, 0 insertions(+), 0 deletions(-) diff --git a/test/jdk/java/lang/Class/forName/classes/semicolon.class b/test/jdk/java/lang/Class/forName/classes/semicolon.class index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..a1524080ae3be1702a1a7c2b4c4400df09d39ec8 100644 GIT binary patch literal 408 zcmZutJx{|h5PeS5I0=E4mXyy93`l{Y5pxg=5@M(TDTswBX|2jt5~GlS_*pQ3#J~^W zM$+ktTWI zusOCp>|mF{yAoNZq8C+W(-Fs>hkYC{u!y0%)VxXOVp6R@@#|A1a78RhoLC)gVm^hS!-0wl^B eJgPPIs2K&EcNo3a2h1hir4|}ht-DUOfsH?OV^9qM literal 0 HcmV?d00001 diff --git a/test/jdk/sun/misc/Hello.class b/test/jdk/sun/misc/Hello.class index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..07bb8bd4bb089a2ceb50549d11548fbb806310ab 100644 GIT binary patch literal 401 zcmZvY%SyvQ6o&uFZJIIKnwolFxDcYCd4P%=L0l9SB5qtw>QJWSQerCjSh`Sf;RE#@4j1{PN;&#O}d z2H@y$3<7Loi@|L(9NPhQu*=X}G`q>BYTPVI>C0223ffK8HAD0_Sy#y|jcsVSlEsjr z-}YFR8TiaVIqe+9|E-Jzxb!RLSRfo7vOeAR$usiq@dwx|1@s=WUMq4!RuE8Z(8IPA Y@ZVsC_B)&fE+|C_>M96crP#vSFLNSJ-~a#s literal 0 HcmV?d00001 diff --git a/test/jdk/sun/security/tools/jarsigner/oldsig/A.class b/test/jdk/sun/security/tools/jarsigner/oldsig/A.class index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..88a98f09e00f1dc61bff002e97393e4351e5c6d4 100644 GIT binary patch literal 176 zcmX^0Z`VEs1_mPrUM>b^1}=66ZgvJ9Mg}&U%)HDJJ4Oa(4b3n{1{UZ1lvG9rexJ;| zRKL>Pq|~C2#H1Xc2v=}^X;E^jTPBFZ=BSsISeD4cz{0@F$iV2x$RGgX>*plqrR)1A zWu+#UFeorE0qp?+Mj!?%1k!9kmMoA4iLh#IXJFh2mSzW%Y+yl<6bF#U#J~vvV?P{> literal 0 HcmV?d00001 From 3b4e77dc9945ff8941af9a2f2c97e6e5b1378cfd Mon Sep 17 00:00:00 2001 From: Vicente Romero Date: Fri, 15 Aug 2025 19:22:28 -0400 Subject: [PATCH 06/10] minor fixes --- .../classes/com/sun/tools/javac/comp/Attr.java | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) 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 20cf6416104..63b741cd369 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 @@ -1256,7 +1256,7 @@ public void visitMethodDef(JCMethodDecl tree) { ListBuffer prologueCode = new ListBuffer<>(); for (JCTree stat : tree.body.stats) { prologueCode.add(stat); - // gather all the stats in the body until the super or this invocation is found, including it + // gather all the stats in the body until a `super` or `this` invocation is found if (stat instanceof JCExpressionStatement expStmt && expStmt.expr instanceof JCMethodInvocation mi && TreeInfo.isConstructorCall(mi)) { @@ -1373,12 +1373,6 @@ public void visitReference(JCMemberReference tree) { @Override public void visitAssign(JCAssign tree) { super.visitAssign(tree); - /*Symbol sym = TreeInfo.symbolFor(tree.lhs); - if (sym != null && - (sym.flags() & HASINIT) != 0 && - sym.owner == localEnv.enclClass.sym) { - log.error(tree.lhs, Errors.CantAssignInitializedBeforeCtorCalled(sym)); - }*/ if (tree.rhs.type.constValue() == null) { analyzeTree(tree.rhs); } @@ -1528,10 +1522,9 @@ public void visitVarDef(JCVariableDecl tree) { //fixup local variable type v.type = chk.checkLocalVarType(tree, tree.init.type, tree.name); } - // don't analyze if we are already inside a constructor's prologue - if (!previousCtorPrologue && initEnv.info.ctorPrologue) { + if (v.owner.kind == TYP && !v.isStatic() && v.isStrict()) { CtorPrologueVisitor ctorPrologueVisitor = new CtorPrologueVisitor(initEnv); - ctorPrologueVisitor.scan(tree); + ctorPrologueVisitor.scan(tree.init); } } finally { initEnv.info.ctorPrologue = previousCtorPrologue; From c175f7631ecd9237edcb8ee37e387d642b756c8e Mon Sep 17 00:00:00 2001 From: Vicente Romero Date: Fri, 15 Aug 2025 21:38:31 -0400 Subject: [PATCH 07/10] test changes --- .../tools/javac/SuperInit/EarlyAssignments.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/test/langtools/tools/javac/SuperInit/EarlyAssignments.java b/test/langtools/tools/javac/SuperInit/EarlyAssignments.java index c3cad5d7016..571f4f01432 100644 --- a/test/langtools/tools/javac/SuperInit/EarlyAssignments.java +++ b/test/langtools/tools/javac/SuperInit/EarlyAssignments.java @@ -18,9 +18,9 @@ public Inner1() { } public Inner1(int y) { - y = x; // FAIL - early 'this' reference - y = this.x; // FAIL - early 'this' reference - y = Inner1.this.x; // FAIL - early 'this' reference + y = x; // OK - "x" belongs to this class + y = this.x; // OK - "x" belongs to this class + y = Inner1.this.x; // OK - "x" belongs to this class super(); } @@ -95,19 +95,19 @@ public static class Inner4 { public Inner4() { x = 0; // OK - x = x + 1; // FAIL - illegal early access + x = x + 1; // OK super(); } public Inner4(int a) { this.x = 0; // OK - this.x = this.x + 1; // FAIL - illegal early access + this.x = this.x + 1; // OK super(); } public Inner4(char a) { Inner4.this.x = 0; // OK - Inner4.this.x = Inner4.this.x + 1; // FAIL - illegal early access + Inner4.this.x = Inner4.this.x + 1; // OK super(); } } From 6433fe2ca5a2f1cd1bfa786efa98505db5abf45c Mon Sep 17 00:00:00 2001 From: Vicente Romero Date: Mon, 18 Aug 2025 12:20:48 -0400 Subject: [PATCH 08/10] refactoring --- .../com/sun/tools/javac/comp/Attr.java | 27 +++++++++++-------- 1 file changed, 16 insertions(+), 11 deletions(-) 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 63b741cd369..314d4a8abb5 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 @@ -1256,7 +1256,9 @@ public void visitMethodDef(JCMethodDecl tree) { ListBuffer prologueCode = new ListBuffer<>(); for (JCTree stat : tree.body.stats) { prologueCode.add(stat); - // gather all the stats in the body until a `super` or `this` invocation is found + /* gather all the stats in the body until a `super` or `this` constructor invocation is found, + * the constructor invocation should also be included + */ if (stat instanceof JCExpressionStatement expStmt && expStmt.expr instanceof JCMethodInvocation mi && TreeInfo.isConstructorCall(mi)) { @@ -1288,25 +1290,28 @@ class CtorPrologueVisitor extends TreeScanner { @Override public void visitLambda(JCLambda lambda) { super.visitLambda(lambda); - java.util.List symbols = TreeInfo.symbolsFor(lambda.body); - for (TreeInfo.SymAndTree symAndTree : symbols) { - Symbol sym = symAndTree.symbol(); - JCTree tree = filter(symAndTree.tree()); - if (sym.kind == VAR && rs.isEarlyReference(localEnv, tree instanceof JCFieldAccess fa ? fa.selected : null, (VarSymbol) sym)) { - log.error(tree, Errors.CantRefBeforeCtorCalled(sym)); - } - } + // lambda in prologue + classDeclAndLambdaHelper(TreeInfo.symbolsFor(lambda.body)); } @Override public void visitClassDef(JCClassDecl classDecl) { super.visitClassDef(classDecl); // local class in prologue - java.util.List symbols = TreeInfo.symbolsFor(classDecl.defs); + classDeclAndLambdaHelper(TreeInfo.symbolsFor(classDecl.defs)); + } + + private void classDeclAndLambdaHelper(java.util.List symbols) { for (TreeInfo.SymAndTree symAndTree : symbols) { Symbol sym = symAndTree.symbol(); JCTree tree = filter(symAndTree.tree()); - if (sym.kind == VAR && rs.isEarlyReference(localEnv, tree instanceof JCFieldAccess fa ? fa.selected : null, (VarSymbol) sym)) { + if (sym.kind == VAR && + rs.isEarlyReference( + localEnv, + tree instanceof JCFieldAccess fa ? + fa.selected : + null, + (VarSymbol) sym)) { log.error(tree, Errors.CantRefBeforeCtorCalled(sym)); } } From 399bd5104e39c9ccef459f70e12be38bef86f97e Mon Sep 17 00:00:00 2001 From: Vicente Romero Date: Mon, 18 Aug 2025 12:29:49 -0400 Subject: [PATCH 09/10] more changes --- .../com/sun/tools/javac/comp/Attr.java | 38 +++++++++---------- 1 file changed, 18 insertions(+), 20 deletions(-) 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 314d4a8abb5..1b4cb6f7782 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 @@ -1257,7 +1257,7 @@ public void visitMethodDef(JCMethodDecl tree) { for (JCTree stat : tree.body.stats) { prologueCode.add(stat); /* gather all the stats in the body until a `super` or `this` constructor invocation is found, - * the constructor invocation should also be included + * the constructor invocation will also be included */ if (stat instanceof JCExpressionStatement expStmt && expStmt.expr instanceof JCMethodInvocation mi && @@ -1324,17 +1324,8 @@ public void visitApply(JCMethodInvocation tree) { boolean isConstructorCall = name == names._this || name == names._super; Symbol msym = TreeInfo.symbolFor(tree.meth); if (!isConstructorCall && !msym.isStatic()) { - if (msym.owner == env.enclClass.sym) { - // instance method? - if (tree.meth instanceof JCFieldAccess fa) { - if (TreeInfo.isExplicitThisReference(types, (ClassType)env.enclClass.sym.type, fa.selected)) { - log.error(tree.meth, Errors.CantRefBeforeCtorCalled(msym)); - } - } else { - log.error(tree.meth, Errors.CantRefBeforeCtorCalled(msym)); - } - } else if (msym.isMemberOf(env.enclClass.sym, types)){ - // here we are dealing with an inherited method, probably an error too + if (msym.owner == env.enclClass.sym || + msym.isMemberOf(env.enclClass.sym, types)) { if (tree.meth instanceof JCFieldAccess fa) { if (TreeInfo.isExplicitThisReference(types, (ClassType)env.enclClass.sym.type, fa.selected)) { log.error(tree.meth, Errors.CantRefBeforeCtorCalled(msym)); @@ -1360,18 +1351,22 @@ public void visitApply(JCMethodInvocation tree) { @Override public void visitNewClass(JCNewClass tree) { super.visitNewClass(tree); - if (tree.type.tsym.isEnclosedBy(env.enclClass.sym) && !tree.type.tsym.isStatic() && !tree.type.tsym.isDirectlyOrIndirectlyLocal()) { - log.error(tree, Errors.CantRefBeforeCtorCalled(tree.constructor)); - } + checkNewClassAndMethRefs(tree, tree.type); } @Override public void visitReference(JCMemberReference tree) { super.visitReference(tree); if (tree.getMode() == JCMemberReference.ReferenceMode.NEW) { - if (tree.expr.type.tsym.isEnclosedBy(env.enclClass.sym) && !tree.expr.type.tsym.isStatic() && !tree.expr.type.tsym.isDirectlyOrIndirectlyLocal()) { - log.error(tree, Errors.CantRefBeforeCtorCalled(tree.expr.type.getEnclosingType().tsym)); - } + checkNewClassAndMethRefs(tree, tree.expr.type); + } + } + + void checkNewClassAndMethRefs(JCTree tree, Type t) { + if (t.tsym.isEnclosedBy(env.enclClass.sym) && + !t.tsym.isStatic() && + !t.tsym.isDirectlyOrIndirectlyLocal()) { + log.error(tree, Errors.CantRefBeforeCtorCalled(t.getEnclosingType().tsym)); } } @@ -1419,8 +1414,11 @@ void analyzeTree(JCTree jcTree) { if (!tree.hasTag(IDENT) && !tree.hasTag(SELECT)) { throw new AssertionError("unexpected tree " + tree + " with tag " + tree.getTag()); } - Symbol owner = tree.hasTag(IDENT) ? sym.owner : ((JCFieldAccess)tree).selected.type.tsym; - if (localEnv.enclClass.sym.isSubClass(owner, types) && sym.isInheritedIn(localEnv.enclClass.sym, types)) { + Symbol owner = tree.hasTag(IDENT) ? + sym.owner : + ((JCFieldAccess)tree).selected.type.tsym; + if (localEnv.enclClass.sym.isSubClass(owner, types) && + sym.isInheritedIn(localEnv.enclClass.sym, types)) { log.error(tree, Errors.CantRefBeforeCtorCalled(sym)); } } else { From 841bfc04ead2b9a136be61c8fc9ad3f917064125 Mon Sep 17 00:00:00 2001 From: Vicente Romero Date: Tue, 19 Aug 2025 09:23:36 -0400 Subject: [PATCH 10/10] renaming methods in LocalProxyVarGen --- .../com/sun/tools/javac/comp/Attr.java | 2 +- .../tools/javac/comp/LocalProxyVarsGen.java | 40 +++++++++---------- .../javac/SuperInit/EarlyAssignments.out | 2 +- .../tools/javac/SuperInit/SuperInitFails.out | 4 +- .../SuperInit/ValueClassSuperInitFails.out | 4 +- .../NewBeforeOuterConstructed.out | 2 +- .../NewBeforeOuterConstructed2.out | 2 +- 7 files changed, 28 insertions(+), 28 deletions(-) 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 1b4cb6f7782..82966a53b2f 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 @@ -1425,7 +1425,7 @@ void analyzeTree(JCTree jcTree) { if ((sym.isFinal() || sym.isStrict()) && sym.kind == VAR && sym.owner.kind == TYP) - localProxyVarsGen.addStrictFieldReadInPrologue(localEnv.enclMethod, sym); + localProxyVarsGen.addFinalOrStrictFieldReadInPrologue(localEnv.enclMethod, sym); } } } diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/LocalProxyVarsGen.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/LocalProxyVarsGen.java index dea2dbfaf66..682c1a42c0e 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/LocalProxyVarsGen.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/LocalProxyVarsGen.java @@ -88,8 +88,8 @@ public static LocalProxyVarsGen instance(Context context) { private TreeMaker make; private final UnsetFieldsInfo unsetFieldsInfo; private ClassSymbol currentClass = null; - private java.util.List strictInstanceFields; - private Map> strictFieldsReadInPrologue = new HashMap<>(); + private java.util.List finalOrStrictInstanceFields; + private Map> finalOrStrictFieldsReadInPrologue = new HashMap<>(); private final boolean noLocalProxyVars; @@ -105,10 +105,10 @@ protected LocalProxyVarsGen(Context context) { noLocalProxyVars = options.isSet("noLocalProxyVars"); } - public void addStrictFieldReadInPrologue(JCMethodDecl constructor, Symbol sym) { - Set fieldSet = strictFieldsReadInPrologue.getOrDefault(constructor, new HashSet<>()); + public void addFinalOrStrictFieldReadInPrologue(JCMethodDecl constructor, Symbol sym) { + Set fieldSet = finalOrStrictFieldsReadInPrologue.getOrDefault(constructor, new HashSet<>()); fieldSet.add(sym); - strictFieldsReadInPrologue.put(constructor, fieldSet); + finalOrStrictFieldsReadInPrologue.put(constructor, fieldSet); } public JCTree translateTopLevelClass(JCTree cdef, TreeMaker make) { @@ -128,41 +128,41 @@ public JCTree translateTopLevelClass(JCTree cdef, TreeMaker make) { @Override public void visitClassDef(JCClassDecl tree) { ClassSymbol prevCurrentClass = currentClass; - java.util.List prevStrictInstanceFields = strictInstanceFields; + java.util.List prevFinalOrStrictInstanceFields = finalOrStrictInstanceFields; try { currentClass = tree.sym; - strictInstanceFields = tree.defs.stream() + finalOrStrictInstanceFields = tree.defs.stream() .filter(t -> t.hasTag(VARDEF)) .map(t -> (JCVariableDecl)t) - .filter(vd -> vd.sym.isStrict() && !vd.sym.isStatic()) + .filter(vd -> (vd.sym.isStrict() || vd.sym.isFinal()) && !vd.sym.isStatic()) .collect(List.collector()); super.visitClassDef(tree); } finally { currentClass = prevCurrentClass; - strictInstanceFields = prevStrictInstanceFields; + finalOrStrictInstanceFields = prevFinalOrStrictInstanceFields; } } public void visitMethodDef(JCMethodDecl tree) { - if (strictFieldsReadInPrologue.get(tree) != null) { - Set fieldSet = strictFieldsReadInPrologue.get(tree); - java.util.List strictFieldsRead = new ArrayList<>(); - for (JCVariableDecl sfield : strictInstanceFields) { - if (fieldSet.contains(sfield.sym)) { - strictFieldsRead.add(sfield); + if (finalOrStrictFieldsReadInPrologue.get(tree) != null) { + Set fieldSet = finalOrStrictFieldsReadInPrologue.get(tree); + java.util.List finalOrStrictFieldsRead = new ArrayList<>(); + for (JCVariableDecl field : finalOrStrictInstanceFields) { + if (fieldSet.contains(field.sym)) { + finalOrStrictFieldsRead.add(field); } } - addLocalProxiesFor(tree, strictFieldsRead); - strictFieldsReadInPrologue.remove(tree); + addLocalProxiesFor(tree, finalOrStrictFieldsRead); + finalOrStrictFieldsReadInPrologue.remove(tree); } super.visitMethodDef(tree); } - void addLocalProxiesFor(JCMethodDecl constructor, java.util.List multiAssignedStrictFields) { + void addLocalProxiesFor(JCMethodDecl constructor, java.util.List finalOrStrictFields) { ListBuffer localDeclarations = new ListBuffer<>(); Map fieldToLocalMap = new LinkedHashMap<>(); - for (JCVariableDecl fieldDecl : multiAssignedStrictFields) { + for (JCVariableDecl fieldDecl : finalOrStrictFields) { long flags = SYNTHETIC; VarSymbol proxy = new VarSymbol(flags, newLocalName(fieldDecl.name.toString()), fieldDecl.sym.erasure(types), constructor.sym); fieldToLocalMap.put(fieldDecl.sym, proxy); @@ -211,7 +211,7 @@ void addLocalProxiesFor(JCMethodDecl constructor, java.util.List } } - Name newLocalName(String name) { + private Name newLocalName(String name) { return names.fromString("local" + target.syntheticNameChar() + name); } diff --git a/test/langtools/tools/javac/SuperInit/EarlyAssignments.out b/test/langtools/tools/javac/SuperInit/EarlyAssignments.out index 586f2486dde..827dddce6a8 100644 --- a/test/langtools/tools/javac/SuperInit/EarlyAssignments.out +++ b/test/langtools/tools/javac/SuperInit/EarlyAssignments.out @@ -17,7 +17,7 @@ EarlyAssignments.java:134:22: compiler.err.cant.ref.before.ctor.called: x EarlyAssignments.java:139:28: compiler.err.cant.ref.before.ctor.called: x EarlyAssignments.java:148:13: compiler.err.cant.assign.initialized.before.ctor.called: x EarlyAssignments.java:157:13: compiler.err.cant.assign.val.to.var: final, x -EarlyAssignments.java:168:18: compiler.err.cant.ref.before.ctor.called: EarlyAssignments.Inner8.Inner8a() +EarlyAssignments.java:168:18: compiler.err.cant.ref.before.ctor.called: EarlyAssignments.Inner8 - compiler.note.preview.filename: EarlyAssignments.java, DEFAULT - compiler.note.preview.recompile 20 errors diff --git a/test/langtools/tools/javac/SuperInit/SuperInitFails.out b/test/langtools/tools/javac/SuperInit/SuperInitFails.out index 5fca1d0db83..5fe959ea908 100644 --- a/test/langtools/tools/javac/SuperInit/SuperInitFails.out +++ b/test/langtools/tools/javac/SuperInit/SuperInitFails.out @@ -8,11 +8,11 @@ SuperInitFails.java:104:14: compiler.err.cant.ref.before.ctor.called: this SuperInitFails.java:108:20: compiler.err.not.encl.class: java.lang.Object SuperInitFails.java:112:23: compiler.err.cant.ref.before.ctor.called: spliterator() SuperInitFails.java:119:22: compiler.err.call.must.only.appear.in.ctor -SuperInitFails.java:125:9: compiler.err.cant.ref.before.ctor.called: SuperInitFails.Inner1() +SuperInitFails.java:125:9: compiler.err.cant.ref.before.ctor.called: SuperInitFails SuperInitFails.java:133:9: compiler.err.non.canonical.constructor.invoke.another.constructor: SuperInitFails.Record1 SuperInitFails.java:138:9: compiler.err.non.canonical.constructor.invoke.another.constructor: SuperInitFails.Record2 SuperInitFails.java:155:50: compiler.err.cant.ref.before.ctor.called: x -SuperInitFails.java:159:15: compiler.err.cant.ref.before.ctor.called: SuperInitFails.Inner1() +SuperInitFails.java:159:15: compiler.err.cant.ref.before.ctor.called: SuperInitFails SuperInitFails.java:168:13: compiler.err.cant.ref.before.ctor.called: x SuperInitFails.java:172:17: compiler.err.cant.ref.before.ctor.called: x SuperInitFails.java:176:24: compiler.err.cant.ref.before.ctor.called: x diff --git a/test/langtools/tools/javac/SuperInit/ValueClassSuperInitFails.out b/test/langtools/tools/javac/SuperInit/ValueClassSuperInitFails.out index 660cd827b62..9ce5ced7c4d 100644 --- a/test/langtools/tools/javac/SuperInit/ValueClassSuperInitFails.out +++ b/test/langtools/tools/javac/SuperInit/ValueClassSuperInitFails.out @@ -8,12 +8,12 @@ ValueClassSuperInitFails.java:114:14: compiler.err.cant.ref.before.ctor.called: ValueClassSuperInitFails.java:118:20: compiler.err.not.encl.class: java.lang.Object ValueClassSuperInitFails.java:122:23: compiler.err.cant.ref.before.ctor.called: spliterator() ValueClassSuperInitFails.java:129:22: compiler.err.call.must.only.appear.in.ctor -ValueClassSuperInitFails.java:135:9: compiler.err.cant.ref.before.ctor.called: ValueClassSuperInitFails.Inner1() +ValueClassSuperInitFails.java:135:9: compiler.err.cant.ref.before.ctor.called: ValueClassSuperInitFails ValueClassSuperInitFails.java:143:9: compiler.err.non.canonical.constructor.invoke.another.constructor: ValueClassSuperInitFails.Record1 ValueClassSuperInitFails.java:148:9: compiler.err.non.canonical.constructor.invoke.another.constructor: ValueClassSuperInitFails.Record2 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.Inner1() +ValueClassSuperInitFails.java:179:15: compiler.err.cant.ref.before.ctor.called: ValueClassSuperInitFails 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 diff --git a/test/langtools/tools/javac/implicitThis/NewBeforeOuterConstructed.out b/test/langtools/tools/javac/implicitThis/NewBeforeOuterConstructed.out index 82ecf27db1d..0c251910be0 100644 --- a/test/langtools/tools/javac/implicitThis/NewBeforeOuterConstructed.out +++ b/test/langtools/tools/javac/implicitThis/NewBeforeOuterConstructed.out @@ -1,2 +1,2 @@ -NewBeforeOuterConstructed.java:27:21: compiler.err.cant.ref.before.ctor.called: NewBeforeOuterConstructed.NullOutputStream() +NewBeforeOuterConstructed.java:27:21: compiler.err.cant.ref.before.ctor.called: NewBeforeOuterConstructed 1 error diff --git a/test/langtools/tools/javac/implicitThis/NewBeforeOuterConstructed2.out b/test/langtools/tools/javac/implicitThis/NewBeforeOuterConstructed2.out index 55a619c7a40..4c82aa9d32e 100644 --- a/test/langtools/tools/javac/implicitThis/NewBeforeOuterConstructed2.out +++ b/test/langtools/tools/javac/implicitThis/NewBeforeOuterConstructed2.out @@ -1,2 +1,2 @@ -NewBeforeOuterConstructed2.java:20:35: compiler.err.cant.ref.before.ctor.called: NewBeforeOuterConstructed2.Middle(int) +NewBeforeOuterConstructed2.java:20:35: compiler.err.cant.ref.before.ctor.called: NewBeforeOuterConstructed2 1 error