changeset 49042:89a1f7673896 lworld

[lworld] Withdraw support for assignment syntax for value instance field updates (use __WithField operator instead)
author sadayapalam
date Wed, 07 Mar 2018 11:00:47 +0530
parents 75ebb75d0d60
children 85946f4dc33d
files src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java src/jdk.compiler/share/classes/com/sun/tools/javac/comp/AttrContext.java src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Gen.java src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Items.java test/langtools/tools/javac/valhalla/lworld-values/CheckMakeDefault.java test/langtools/tools/javac/valhalla/lworld-values/FinalFieldTest.java test/langtools/tools/javac/valhalla/lworld-values/FinalFieldTest.out test/langtools/tools/javac/valhalla/lworld-values/FlattenableNegativeTest.java test/langtools/tools/javac/valhalla/lworld-values/FlattenableNegativeTest.out test/langtools/tools/javac/valhalla/lworld-values/Point.java test/langtools/tools/javac/valhalla/lworld-values/ValueCreationTest.java test/langtools/tools/javac/valhalla/lworld-values/WithFieldNegativeTests.java test/langtools/tools/javac/valhalla/lworld-values/WithFieldNegativeTests.out
diffstat 14 files changed, 90 insertions(+), 84 deletions(-) [+]
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