OpenJDK / valhalla / valhalla
changeset 49042:89a1f7673896 lworld
[lworld] Withdraw support for assignment syntax for value instance field updates (use __WithField operator instead)
line wrap: on
line diff
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java Tue Mar 06 18:28:35 2018 +0530 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java Wed Mar 07 11:00:47 2018 +0530 @@ -298,11 +298,11 @@ log.error(pos, Errors.TryResourceMayNotBeAssigned(v)); } else { boolean complain = true; - /* Allow updates to instance fields of value classes by any method in the same nest - - This does not result in mutation of final fields; the code generator would implement - `copy on write' semantics via the opcode `withfield'. + /* Allow updates to instance fields of value classes by any method in the same nest via the + withfield operator -This does not result in mutation of final fields; the code generator + would implement `copy on write' semantics via the opcode `withfield'. */ - if (v.getKind() == ElementKind.FIELD && (v.flags() & STATIC) == 0 && types.isValue(v.owner.type)) { + if (env.info.inWithField && v.getKind() == ElementKind.FIELD && (v.flags() & STATIC) == 0 && types.isValue(v.owner.type)) { if (env.enclClass.sym.outermostClass() == v.owner.outermostClass()) complain = false; } @@ -1329,19 +1329,25 @@ } public void visitWithField(JCWithField tree) { - Type fieldtype = attribTree(tree.field, env.dup(tree), varAssignmentInfo); - attribExpr(tree.value, env, fieldtype); - Type capturedType = syms.errType; - if (tree.field.type != null && !tree.field.type.isErroneous()) { - final Symbol sym = TreeInfo.symbol(tree.field); - if (sym == null || sym.kind != VAR || sym.owner.kind != TYP || - (sym.flags() & STATIC) != 0 || !types.isValue(sym.owner.type)) { - log.error(tree.field.pos(), Errors.ValueInstanceFieldExpectedHere); - } else { - capturedType = capture(sym.owner.type); - } - } - result = check(tree, capturedType, KindSelector.VAL, resultInfo); + boolean inWithField = env.info.inWithField; + try { + env.info.inWithField = true; + Type fieldtype = attribTree(tree.field, env.dup(tree), varAssignmentInfo); + attribExpr(tree.value, env, fieldtype); + Type capturedType = syms.errType; + if (tree.field.type != null && !tree.field.type.isErroneous()) { + final Symbol sym = TreeInfo.symbol(tree.field); + if (sym == null || sym.kind != VAR || sym.owner.kind != TYP || + (sym.flags() & STATIC) != 0 || !types.isValue(sym.owner.type)) { + log.error(tree.field.pos(), Errors.ValueInstanceFieldExpectedHere); + } else { + capturedType = capture(sym.owner.type); + } + } + result = check(tree, capturedType, KindSelector.VAL, resultInfo); + } finally { + env.info.inWithField = inWithField; + } } public void visitForLoop(JCForLoop tree) {
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/AttrContext.java Tue Mar 06 18:28:35 2018 +0530 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/AttrContext.java Wed Mar 07 11:00:47 2018 +0530 @@ -79,6 +79,11 @@ */ boolean isNewClass = false; + /** + * Is this an attribution environment for a withfield operation ? + */ + boolean inWithField = false; + /** Indicate if the type being visited is a service implementation */ boolean visitingServiceImplementation = false; @@ -130,6 +135,7 @@ info.isSpeculative = isSpeculative; info.isAnonymousDiamond = isAnonymousDiamond; info.isNewClass = isNewClass; + info.inWithField = inWithField; info.preferredTreeForDiagnostics = preferredTreeForDiagnostics; info.visitingServiceImplementation = visitingServiceImplementation; return info;
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java Tue Mar 06 18:28:35 2018 +0530 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java Wed Mar 07 11:00:47 2018 +0530 @@ -44,8 +44,6 @@ import com.sun.tools.javac.code.Symbol.*; import com.sun.tools.javac.tree.JCTree.*; -import javax.lang.model.element.ElementKind; - import static com.sun.tools.javac.code.Flags.*; import static com.sun.tools.javac.code.Flags.BLOCK; import static com.sun.tools.javac.code.Kinds.Kind.*; @@ -1543,7 +1541,6 @@ } private boolean isInitialConstructor = false; - private JCMethodDecl enclMethod = null; @Override protected void markDead() { @@ -1629,13 +1626,7 @@ } inits.incl(sym.adr); } else if ((sym.flags() & FINAL) != 0) { - boolean complain = true; - if (sym.getKind() == ElementKind.FIELD && (sym.flags() & STATIC) == 0 && types.isValue(sym.owner.type)) { - if (enclMethod != null && enclMethod.sym.owner.outermostClass() == sym.owner.outermostClass()) - complain = false; - } - if (complain) - log.error(pos, Errors.VarMightAlreadyBeAssigned(sym)); + log.error(pos, Errors.VarMightAlreadyBeAssigned(sym)); } } //where @@ -1875,10 +1866,8 @@ Assert.check(pendingExits.isEmpty()); boolean lastInitialConstructor = isInitialConstructor; - JCMethodDecl lastEnclMethod = enclMethod; try { isInitialConstructor = TreeInfo.isInitialConstructor(tree); - enclMethod = tree; if (!isInitialConstructor) { firstadr = nextadr; @@ -1934,7 +1923,6 @@ firstadr = firstadrPrev; returnadr = returnadrPrev; isInitialConstructor = lastInitialConstructor; - enclMethod = lastEnclMethod; } } finally { lint = lintPrev;
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Gen.java Tue Mar 06 18:28:35 2018 +0530 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Gen.java Wed Mar 07 11:00:47 2018 +0530 @@ -2144,14 +2144,10 @@ code.emitop0(arraylength); result = items.makeStackItem(syms.intType); } else { - boolean requireCopyOnWrite = false; - if (sym.kind == VAR && (sym.flags() & (SYNTHETIC | FINAL)) == FINAL && types.isValue(sym.owner.type)) { - requireCopyOnWrite = true; - } result = items. makeMemberItem(sym, (sym.flags() & PRIVATE) != 0 || - selectSuper || accessSuper, (requireCopyOnWrite ? base : null)); + selectSuper || accessSuper); } } }
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Items.java Tue Mar 06 18:28:35 2018 +0530 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Items.java Wed Mar 07 11:00:47 2018 +0530 @@ -150,19 +150,9 @@ * @param member The represented symbol. * @param nonvirtual Is the reference not virtual? (true for constructors * and private members). - * @param baseToCopyOnWrite Updates to fields imply copy on write to this receiver - */ - Item makeMemberItem(Symbol member, boolean nonvirtual, Item baseToCopyOnWrite) { - return baseToCopyOnWrite != null ? new CopyOnWriteMemberItem(baseToCopyOnWrite, member) : new MemberItem(member, nonvirtual); - } - - /** Make an item representing an instance variable or method. - * @param member The represented symbol. - * @param nonvirtual Is the reference not virtual? (true for constructors - * and private members). */ Item makeMemberItem(Symbol member, boolean nonvirtual) { - return makeMemberItem(member, nonvirtual, null); + return new MemberItem(member, nonvirtual); } /** Make an item representing a literal. @@ -564,21 +554,6 @@ } } - class CopyOnWriteMemberItem extends MemberItem { - - Item rcvItem; - - CopyOnWriteMemberItem(Item rcvItem, Symbol member) { - super(member, false); - this.rcvItem = rcvItem; - } - - void store() { - code.emitop2(withfield, pool.put(member)); - rcvItem.store(); - } - } - /** An item representing a literal. */ class ImmediateItem extends Item {
--- a/test/langtools/tools/javac/valhalla/lworld-values/CheckMakeDefault.java Tue Mar 06 18:28:35 2018 +0530 +++ b/test/langtools/tools/javac/valhalla/lworld-values/CheckMakeDefault.java Wed Mar 07 11:00:47 2018 +0530 @@ -35,8 +35,8 @@ String s = __MakeDefault String(); // NO: String cannot be produced in this factory. __MakeDefault SinnerValue(); p = __MakeDefault Point(); - p.x = x; - p.y = y; + p = __WithField(p.x, x); + p = __WithField(p.y, y); return p; } }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/langtools/tools/javac/valhalla/lworld-values/FinalFieldTest.java Wed Mar 07 11:00:47 2018 +0530 @@ -0,0 +1,22 @@ +/* + * @test /nodynamiccopyright/ + * @summary Test that final fields of value classes follow the same assignment rules as vanilla classes. + * @compile/fail/ref=FinalFieldTest.out --should-stop:at=FLOW -XDrawDiagnostics FinalFieldTest.java + */ + +final __ByValue class Blah { + final int x = 10; + final int y; + Blah() { + x = 10; + x = 10; + y = 10; + y = 10; + } + void foo() { + x = 10; + x = 10; + y = 10; + y = 10; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/langtools/tools/javac/valhalla/lworld-values/FinalFieldTest.out Wed Mar 07 11:00:47 2018 +0530 @@ -0,0 +1,8 @@ +FinalFieldTest.java:11:9: compiler.err.cant.assign.val.to.final.var: x +FinalFieldTest.java:12:9: compiler.err.cant.assign.val.to.final.var: x +FinalFieldTest.java:17:9: compiler.err.cant.assign.val.to.final.var: x +FinalFieldTest.java:18:9: compiler.err.cant.assign.val.to.final.var: x +FinalFieldTest.java:19:9: compiler.err.cant.assign.val.to.final.var: y +FinalFieldTest.java:20:9: compiler.err.cant.assign.val.to.final.var: y +FinalFieldTest.java:14:9: compiler.err.var.might.already.be.assigned: y +7 errors
--- a/test/langtools/tools/javac/valhalla/lworld-values/FlattenableNegativeTest.java Tue Mar 06 18:28:35 2018 +0530 +++ b/test/langtools/tools/javac/valhalla/lworld-values/FlattenableNegativeTest.java Wed Mar 07 11:00:47 2018 +0530 @@ -14,12 +14,12 @@ __Flattenable final V v2 = v; // OK, null not constant propagated. V foo(X x) { - x.v = null; // Error: withfield attempt is illegal. + x = __WithField(x.v, null); // Error: withfield attempt is illegal. return x.v; } } V foo(X x) { - x.v = null; // withfield attempt is illegal + x = __WithField(x.v, null); // withfield attempt is illegal return x.v; } @@ -28,7 +28,7 @@ V [] va = { null }; // Illegal array initialization V [] va2 = new V[] { null }; // Illegal array initialization void foo(X x) { - x.v = null; // illegal withfield attempt + x = __WithField(x.v, null); // illegal withfield attempt v = null; // illegal assignment. va[0] = null; // Illegal. va = new V[] { null }; // Illegal
--- a/test/langtools/tools/javac/valhalla/lworld-values/FlattenableNegativeTest.out Tue Mar 06 18:28:35 2018 +0530 +++ b/test/langtools/tools/javac/valhalla/lworld-values/FlattenableNegativeTest.out Wed Mar 07 11:00:47 2018 +0530 @@ -1,9 +1,9 @@ FlattenableNegativeTest.java:13:39: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: compiler.misc.type.null, FlattenableNegativeTest.V) -FlattenableNegativeTest.java:17:23: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: compiler.misc.type.null, FlattenableNegativeTest.V) -FlattenableNegativeTest.java:22:19: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: compiler.misc.type.null, FlattenableNegativeTest.V) +FlattenableNegativeTest.java:17:38: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: compiler.misc.type.null, FlattenableNegativeTest.V) +FlattenableNegativeTest.java:22:34: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: compiler.misc.type.null, FlattenableNegativeTest.V) FlattenableNegativeTest.java:28:25: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: compiler.misc.type.null, FlattenableNegativeTest.V) FlattenableNegativeTest.java:29:34: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: compiler.misc.type.null, FlattenableNegativeTest.V) -FlattenableNegativeTest.java:31:23: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: compiler.misc.type.null, FlattenableNegativeTest.V) +FlattenableNegativeTest.java:31:38: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: compiler.misc.type.null, FlattenableNegativeTest.V) FlattenableNegativeTest.java:32:21: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: compiler.misc.type.null, FlattenableNegativeTest.V) FlattenableNegativeTest.java:33:25: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: compiler.misc.type.null, FlattenableNegativeTest.V) FlattenableNegativeTest.java:34:32: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: compiler.misc.type.null, FlattenableNegativeTest.V)
--- a/test/langtools/tools/javac/valhalla/lworld-values/Point.java Tue Mar 06 18:28:35 2018 +0530 +++ b/test/langtools/tools/javac/valhalla/lworld-values/Point.java Wed Mar 07 11:00:47 2018 +0530 @@ -40,8 +40,8 @@ } static Point makePoint(int x, int y) { Point p = __MakeDefault Point(); - p.x = x; - p.y = y; + p = __WithField(p.x, x); + p = __WithField(p.y, y); return p; } }
--- a/test/langtools/tools/javac/valhalla/lworld-values/ValueCreationTest.java Tue Mar 06 18:28:35 2018 +0530 +++ b/test/langtools/tools/javac/valhalla/lworld-values/ValueCreationTest.java Wed Mar 07 11:00:47 2018 +0530 @@ -49,9 +49,8 @@ static Point makePoint(int x, int y) { Point p = __MakeDefault Point(); - p.x = x; - p.y = y; - return p; + p = __WithField(p.x, x); + return __WithField(p.y, y); } public static void main(String [] args) { @@ -78,9 +77,7 @@ "10: aload_2", "11: iload_1", "12: withfield #3 // Field y:I", - "15: astore_2", - "16: aload_2", - "17: areturn" + "15: areturn" });
--- a/test/langtools/tools/javac/valhalla/lworld-values/WithFieldNegativeTests.java Tue Mar 06 18:28:35 2018 +0530 +++ b/test/langtools/tools/javac/valhalla/lworld-values/WithFieldNegativeTests.java Wed Mar 07 11:00:47 2018 +0530 @@ -14,8 +14,8 @@ final A a = __MakeDefault A(); void foo(A a) { - a.x = 100; // OK, same nest. - a.sx = 100; // Error. + a.x = 100; + a.sx = 100; } } @@ -24,8 +24,8 @@ } void foo(A a, final A fa) { - a.x = 100; // OK. - (a).x = 100; // OK. + a.x = 100; + (a).x = 100; fa.x = 100; x = 100; this.x = 100; @@ -35,7 +35,7 @@ class C { void foo(A a) { - a.x = 100; // Not OK. - a.sx = 100; // Error + a.x = 100; + a.sx = 100; } }
--- a/test/langtools/tools/javac/valhalla/lworld-values/WithFieldNegativeTests.out Tue Mar 06 18:28:35 2018 +0530 +++ b/test/langtools/tools/javac/valhalla/lworld-values/WithFieldNegativeTests.out Wed Mar 07 11:00:47 2018 +0530 @@ -1,4 +1,12 @@ +WithFieldNegativeTests.java:17:14: compiler.err.cant.assign.val.to.final.var: x WithFieldNegativeTests.java:18:14: compiler.err.cant.assign.val.to.final.var: sx +WithFieldNegativeTests.java:23:16: compiler.err.cant.assign.val.to.final.var: x +WithFieldNegativeTests.java:27:10: compiler.err.cant.assign.val.to.final.var: x +WithFieldNegativeTests.java:28:12: compiler.err.cant.assign.val.to.final.var: x +WithFieldNegativeTests.java:29:11: compiler.err.cant.assign.val.to.final.var: x +WithFieldNegativeTests.java:30:9: compiler.err.cant.assign.val.to.final.var: x +WithFieldNegativeTests.java:31:13: compiler.err.cant.assign.val.to.final.var: x +WithFieldNegativeTests.java:32:15: compiler.err.cant.assign.val.to.final.var: x WithFieldNegativeTests.java:38:10: compiler.err.cant.assign.val.to.final.var: x WithFieldNegativeTests.java:39:10: compiler.err.cant.assign.val.to.final.var: sx -3 errors +11 errors