changeset 49465:32ff82e6b770 lworld

[lworld] Introduce a new annotation java.lang.ValueBased to distinguish migrating value based classes from pure value types and implement leniet semantics for them; Also flip the default for ACC_Flattenable
author sadayapalam
date Mon, 02 Apr 2018 17:50:51 +0530
parents 76b3740cff03
children 7bb765d53478
files src/java.base/share/classes/java/lang/ValueBased.java src/java.compiler/share/classes/javax/lang/model/element/Modifier.java src/jdk.compiler/share/classes/com/sun/tools/javac/code/Flags.java src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symtab.java src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Lower.java src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java src/jdk.compiler/share/classes/com/sun/tools/javac/parser/Tokens.java src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties src/jdk.jshell/share/classes/jdk/jshell/CompletenessAnalyzer.java test/langtools/tools/javac/diags/examples/BadValueBasedAnno.java test/langtools/tools/javac/diags/examples/SuspiciousNullMix.java test/langtools/tools/javac/valhalla/lworld-values/BadValueBased.java test/langtools/tools/javac/valhalla/lworld-values/BadValueBased.out test/langtools/tools/javac/valhalla/lworld-values/CastNullCheckTest.java test/langtools/tools/javac/valhalla/lworld-values/CheckDefaultFlattenable.java test/langtools/tools/javac/valhalla/lworld-values/CheckNullCastable.out test/langtools/tools/javac/valhalla/lworld-values/DemoteToValueBasedTest.java test/langtools/tools/javac/valhalla/lworld-values/DemoteToValueBasedTest.out test/langtools/tools/javac/valhalla/lworld-values/DemoteToValueBasedTest10.out test/langtools/tools/javac/valhalla/lworld-values/FlattenableFlagTest.java test/langtools/tools/javac/valhalla/lworld-values/Point.java test/langtools/tools/javac/valhalla/lworld-values/ValueBasedWarningsTest.java test/langtools/tools/javac/valhalla/lworld-values/ValueBasedWarningsTest.out
diffstat 27 files changed, 334 insertions(+), 16 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/java/lang/ValueBased.java	Mon Apr 02 17:50:51 2018 +0530
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.lang;
+
+import java.lang.annotation.*;
+
+/**
+ * An informative annotation type used to indicate that a value type existed in a
+ * prior avatar as a <a href="../lang/doc-files/ValueBased.html">value-based</a>
+ * class. Armed with this information, the compiler may choose to treat with leniency 
+ * certain constructs which are erroneous when used with value types, thereby easing the
+ * pain of migration.
+ */
+
+@Documented
+@Retention(RetentionPolicy.CLASS)
+@Target(ElementType.TYPE)
+public @interface ValueBased {}
\ No newline at end of file
--- a/src/java.compiler/share/classes/javax/lang/model/element/Modifier.java	Wed Mar 28 15:10:23 2018 +0200
+++ b/src/java.compiler/share/classes/javax/lang/model/element/Modifier.java	Mon Apr 02 17:50:51 2018 +0530
@@ -69,6 +69,12 @@
      */
     FLATTENABLE,
 
+    /**
+     * The modifier {@code __NotFlattened}
+     * @since 1.11
+     */
+    NOT_FLATTENED,
+
     /** The modifier {@code static} */          STATIC,
     /** The modifier {@code final} */           FINAL,
     /** The modifier {@code transient} */       TRANSIENT,
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Flags.java	Wed Mar 28 15:10:23 2018 +0200
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Flags.java	Mon Apr 02 17:50:51 2018 +0530
@@ -127,7 +127,9 @@
      */
     public static final int HASINIT          = 1<<18;
 
-    // Flag bit 19 is available.
+    /** Flag is set for a value based class.
+     */
+    public static final int VALUEBASED       = 1<<19;
 
     /** Flag is set for compiler-generated anonymous method symbols
      *  that `own' an initializer block.
@@ -323,6 +325,11 @@
      */
     public static final long ANONCONSTR_BASED = 1L<<57;
 
+    /**
+     * Flag that marks field that is a value instance that SHOULD NOT be inlined in the layout.
+     */
+    public static final long NOT_FLATTENED = 1L<<58;
+
     /** Modifier masks.
      */
     public static final int
@@ -336,13 +343,13 @@
         MethodFlags           = AccessFlags | ABSTRACT | STATIC | NATIVE |
                                 SYNCHRONIZED | FINAL | STRICTFP;
     public static final long
-        ExtendedStandardFlags       = (long)StandardFlags | DEFAULT | VALUE | FLATTENABLE,
-        ModifierFlags               = ((long)StandardFlags & ~INTERFACE) | DEFAULT | FLATTENABLE,
+        ExtendedStandardFlags       = (long)StandardFlags | DEFAULT | VALUE | FLATTENABLE | NOT_FLATTENED,
+        ModifierFlags               = ((long)StandardFlags & ~INTERFACE) | DEFAULT | FLATTENABLE | NOT_FLATTENED,
         InterfaceMethodMask         = ABSTRACT | PRIVATE | STATIC | PUBLIC | STRICTFP | DEFAULT,
         AnnotationTypeElementMask   = ABSTRACT | PUBLIC,
         LocalVarFlags               = FINAL | PARAMETER,
         VarFlags              = AccessFlags | FINAL | STATIC |
-                                VOLATILE | TRANSIENT | FLATTENABLE | ENUM,
+                                VOLATILE | TRANSIENT | FLATTENABLE | NOT_FLATTENED | ENUM,
         ReceiverParamFlags          = PARAMETER;
 
 
@@ -358,6 +365,7 @@
             if (0 != (flags & FINAL))     modifiers.add(Modifier.FINAL);
             if (0 != (flags & TRANSIENT)) modifiers.add(Modifier.TRANSIENT);
             if (0 != (flags & FLATTENABLE)) modifiers.add(Modifier.FLATTENABLE);
+            if (0 != (flags & NOT_FLATTENED)) modifiers.add(Modifier.NOT_FLATTENED);
             if (0 != (flags & VOLATILE))  modifiers.add(Modifier.VOLATILE);
             if (0 != (flags & SYNCHRONIZED))
                                           modifiers.add(Modifier.SYNCHRONIZED);
@@ -427,6 +435,7 @@
         PROPRIETARY(Flags.PROPRIETARY),
         UNION(Flags.UNION),
         FLATTENABLE(Flags.FLATTENABLE),
+        NOT_FLATTENED(Flags.NOT_FLATTENED),
         EFFECTIVELY_FINAL(Flags.EFFECTIVELY_FINAL),
         CLASH(Flags.CLASH),
         AUXILIARY(Flags.AUXILIARY),
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symtab.java	Wed Mar 28 15:10:23 2018 +0200
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symtab.java	Mon Apr 02 17:50:51 2018 +0530
@@ -211,6 +211,7 @@
     public final Type documentedType;
     public final Type elementTypeType;
     public final Type functionalInterfaceType;
+    public final Type valueBasedType;
 
     /** The symbol representing the length field of an array.
      */
@@ -544,6 +545,7 @@
         lambdaMetafactory = enterClass("java.lang.invoke.LambdaMetafactory");
         stringConcatFactory = enterClass("java.lang.invoke.StringConcatFactory");
         functionalInterfaceType = enterClass("java.lang.FunctionalInterface");
+        valueBasedType = enterClass("java.lang.ValueBased");
 
         synthesizeEmptyInterfaceIfMissing(autoCloseableType);
         synthesizeEmptyInterfaceIfMissing(cloneableType);
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java	Wed Mar 28 15:10:23 2018 +0200
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java	Mon Apr 02 17:50:51 2018 +0530
@@ -987,6 +987,10 @@
         return t != null && t.tsym != null && (t.tsym.flags() & Flags.VALUE) != 0;
     }
 
+    public boolean isValueBased(Type t) {
+        return t != null && t.tsym != null && (t.tsym.flags() & Flags.VALUEBASED) != 0;
+    }
+
     // <editor-fold defaultstate="collapsed" desc="isSubtype">
     /**
      * Is t an unchecked subtype of s?
@@ -1107,7 +1111,7 @@
                      return isSubtypeNoCapture(t.getUpperBound(), s);
                  case BOT:
                      return
-                         s.hasTag(BOT) || (s.hasTag(CLASS) && !isValue(s)) ||
+                         s.hasTag(BOT) || (s.hasTag(CLASS) && (!isValue(s) || isValueBased(s))) ||
                          s.hasTag(ARRAY) || s.hasTag(TYPEVAR);
                  case WILDCARD: //we shouldn't be here - avoids crash (see 7034495)
                  case NONE:
@@ -1677,7 +1681,7 @@
 
             @Override
             public Boolean visitClassType(ClassType t, Type s) {
-                if (s.hasTag(ERROR) || s.hasTag(BOT) && !isValue(t))
+                if (s.hasTag(ERROR) || s.hasTag(BOT) && (!isValue(s) || isValueBased(s)))
                     return true;
 
                 if (s.hasTag(TYPEVAR)) {
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java	Wed Mar 28 15:10:23 2018 +0200
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java	Mon Apr 02 17:50:51 2018 +0530
@@ -1198,6 +1198,10 @@
                     setSyntheticVariableType(tree, v.type);
                 }
             }
+            if (v.owner.kind == TYP && types.isValue(v.type) && !types.isValueBased(v.type)) {
+                if ((v.flags() & NOT_FLATTENED) == 0)
+                    v.flags_field |= FLATTENABLE;
+            }
             result = tree.type = v.type;
         }
         finally {
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java	Wed Mar 28 15:10:23 2018 +0200
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java	Mon Apr 02 17:50:51 2018 +0530
@@ -561,6 +561,9 @@
         if (req.hasTag(NONE))
             return found;
         if (checkContext.compatible(found, req, checkContext.checkWarner(pos, found, req))) {
+            if (found.hasTag(BOT) && types.isValueBased(req)) {
+                log.warning(pos, Warnings.SuspiciousMixOfNullWithValueBasedClass(req));
+            }
             return found;
         } else {
             if (found.isNumeric() && req.isNumeric()) {
@@ -583,6 +586,9 @@
     }
     Type checkCastable(DiagnosticPosition pos, Type found, Type req, CheckContext checkContext) {
         if (types.isCastable(found, req, castWarner(pos, found, req))) {
+            if (found.hasTag(BOT) && types.isValueBased(req)) {
+                log.warning(pos, Warnings.SuspiciousMixOfNullWithValueBasedClass(req));
+            }
             return req;
         } else {
             checkContext.report(pos, diags.fragment(Fragments.InconvertibleTypes(found, req)));
@@ -2917,6 +2923,13 @@
                 log.error(a.pos(), Errors.BadFunctionalIntfAnno1(Fragments.NotAFunctionalIntf(s)));
             }
         }
+        if (a.annotationType.type.tsym == syms.valueBasedType.tsym) {
+            if (s.isInterface() || s.isEnum()) {
+                log.error(a.pos(), Errors.BadValueBasedAnno);
+            } else {
+                s.flags_field |= VALUEBASED;
+            }
+        }
     }
 
     public void validateTypeAnnotation(JCAnnotation a, boolean isTypeParameter) {
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Lower.java	Wed Mar 28 15:10:23 2018 +0200
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Lower.java	Mon Apr 02 17:50:51 2018 +0530
@@ -2593,7 +2593,7 @@
             tree.expr = translate(tree.expr, tree.type);
         else
             tree.expr = translate(tree.expr);
-        if (Feature.VALUE_TYPES.allowedInSource(source) && types.isValue(tree.type))
+        if (Feature.VALUE_TYPES.allowedInSource(source) && types.isValue(tree.type) && !types.isValueBased(tree.type))
             if (!types.isSameType(tree.expr.type, tree.clazz.type))
                 tree.expr = attr.makeNullCheck(tree.expr);
         result = tree;
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java	Wed Mar 28 15:10:23 2018 +0200
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java	Mon Apr 02 17:50:51 2018 +0530
@@ -2937,8 +2937,7 @@
         }
         if ((flags & ACC_VALUE) != 0) {
             flags &= ~ACC_VALUE;
-            if (allowValueTypes)
-                flags |= VALUE;
+            flags |= allowValueTypes ? VALUE : VALUEBASED;
         }
         return flags & ~ACC_SUPER; // SUPER and SYNCHRONIZED bits overloaded
     }
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java	Wed Mar 28 15:10:23 2018 +0200
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java	Mon Apr 02 17:50:51 2018 +0530
@@ -317,6 +317,7 @@
                 case STATIC:
                 case TRANSIENT:
                 case FLATTENABLE:
+                case NOTFLATTENAED:
                 case NATIVE:
                 case VOLATILE:
                 case SYNCHRONIZED:
@@ -2879,7 +2880,8 @@
             case PUBLIC      : flag = Flags.PUBLIC; break;
             case STATIC      : flag = Flags.STATIC; break;
             case TRANSIENT   : flag = Flags.TRANSIENT; break;
-            case FLATTENABLE : checkSourceLevel(Feature.VALUE_TYPES); flag = Flags.FLATTENABLE; break;
+            case FLATTENABLE :  checkSourceLevel(Feature.VALUE_TYPES); flag = Flags.FLATTENABLE; break;
+            case NOTFLATTENAED: checkSourceLevel(Feature.VALUE_TYPES); flag = Flags.NOT_FLATTENED; break;
             case FINAL       : flag = Flags.FINAL; break;
             case ABSTRACT    : flag = Flags.ABSTRACT; break;
             case NATIVE      : flag = Flags.NATIVE; break;
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/Tokens.java	Wed Mar 28 15:10:23 2018 +0200
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/Tokens.java	Mon Apr 02 17:50:51 2018 +0530
@@ -163,6 +163,7 @@
         THROWS("throws"),
         TRANSIENT("transient"),
         FLATTENABLE("__Flattenable"),
+        NOTFLATTENAED("__NotFlattened"),
         TRY("try"),
         VALUE("__ByValue"),
         VDEFAULT("__MakeDefault"),
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties	Wed Mar 28 15:10:23 2018 +0200
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties	Mon Apr 02 17:50:51 2018 +0530
@@ -3231,4 +3231,11 @@
     value type may not extend another value or class
 
 compiler.err.value.instance.field.expected.here=\
-    withfield operator requires an instance field of a value class here
\ No newline at end of file
+    withfield operator requires an instance field of a value class here
+
+compiler.err.bad.value.based.anno=\
+    Unexpected @ValueBased annotation
+
+# 0: type
+compiler.warn.suspicious.mix.of.null.with.value.based.class=\
+    Suspicious mix of null with value based class {0}
\ No newline at end of file
--- a/src/jdk.jshell/share/classes/jdk/jshell/CompletenessAnalyzer.java	Wed Mar 28 15:10:23 2018 +0200
+++ b/src/jdk.jshell/share/classes/jdk/jshell/CompletenessAnalyzer.java	Mon Apr 02 17:50:51 2018 +0530
@@ -224,6 +224,7 @@
         PUBLIC(TokenKind.PUBLIC, XDECL1),  //  public
         TRANSIENT(TokenKind.TRANSIENT, XDECL1),  //  transient
         FLATTENABLE(TokenKind.FLATTENABLE, XDECL1),  //  __Flattenable
+        NOTFLATTENED(TokenKind.NOTFLATTENAED, XDECL1),  //  __NotFlattened
         VOLATILE(TokenKind.VOLATILE, XDECL1),  //  volatile
 
         // Declarations and type parameters (thus expressions)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/diags/examples/BadValueBasedAnno.java	Mon Apr 02 17:50:51 2018 +0530
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// key: compiler.err.bad.value.based.anno
+
+@ValueBased
+interface I {
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/diags/examples/SuspiciousNullMix.java	Mon Apr 02 17:50:51 2018 +0530
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// key: compiler.warn.suspicious.mix.of.null.with.value.based.class
+
+@ValueBased
+class I {
+    I i = null;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/valhalla/lworld-values/BadValueBased.java	Mon Apr 02 17:50:51 2018 +0530
@@ -0,0 +1,21 @@
+/*
+ * @test /nodynamiccopyright/
+ * @summary Check that improper application of "@ValueBased" annotation are caught
+ * @compile/fail/ref=BadValueBased.out -XDrawDiagnostics -XDdev BadValueBased.java
+ */
+
+public class BadValueBased {
+    @ValueBased 
+    interface X {}
+
+    @ValueBased 
+    @interface A {}
+
+    @ValueBased
+    enum E {}
+
+    @ValueBased 
+    class Y {
+        @ValueBased int x;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/valhalla/lworld-values/BadValueBased.out	Mon Apr 02 17:50:51 2018 +0530
@@ -0,0 +1,5 @@
+BadValueBased.java:8:5: compiler.err.bad.value.based.anno
+BadValueBased.java:11:5: compiler.err.bad.value.based.anno
+BadValueBased.java:14:5: compiler.err.bad.value.based.anno
+BadValueBased.java:19:9: compiler.err.annotation.type.not.applicable
+4 errors
--- a/test/langtools/tools/javac/valhalla/lworld-values/CastNullCheckTest.java	Wed Mar 28 15:10:23 2018 +0200
+++ b/test/langtools/tools/javac/valhalla/lworld-values/CastNullCheckTest.java	Mon Apr 02 17:50:51 2018 +0530
@@ -32,11 +32,23 @@
  */
 
 public class CastNullCheckTest {
+
+    @ValueBased
+    final __ByValue class XX {
+        final int x = 10;
+    }
+
     public static void main(String... args) {
         int caught = 0;
 
         Object o = null;
         try {
+            XX x = (XX) o;
+        } catch (NullPointerException npe) {
+            caught++;
+        }
+
+        try {
             Point p = (Point) o;
         } catch (NullPointerException npe) {
             caught++;
@@ -49,6 +61,6 @@
             caught++;
         }
         if (caught != 1)
-            throw new AssertionError("NPE missing !");
+            throw new AssertionError("Wrong NPE count: " + caught);
     }
-}
\ No newline at end of file
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/valhalla/lworld-values/CheckDefaultFlattenable.java	Mon Apr 02 17:50:51 2018 +0530
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @summary Check default setting of ACC_FLATTENABLE
+ * @modules jdk.jdeps/com.sun.tools.classfile
+ * @compile CheckDefaultFlattenable.java
+ * @run main CheckDefaultFlattenable
+ */
+
+import com.sun.tools.classfile.*;
+
+public final class CheckDefaultFlattenable {
+
+    final __ByValue class X {
+        final int x = 10;
+    }
+    @ValueBased
+    final __ByValue class Y {
+        final int x = 10;
+    }
+
+    X x1;
+    __NotFlattened X x2;
+    __Flattenable X x3;
+
+    Y y1;
+    __NotFlattened Y y2;
+    __Flattenable Y y3;
+
+    public static void main(String[] args) throws Exception {
+        ClassFile cls = ClassFile.read(CheckDefaultFlattenable.class.getResourceAsStream("CheckDefaultFlattenable.class"));
+
+        int checks = 0;
+        for (Field field : cls.fields) {
+            if (field.getName(cls.constant_pool).equals("x1")) {
+                checks ++;
+                if ((field.access_flags.flags & AccessFlags.ACC_FLATTENABLE) == 0)
+                    throw new AssertionError("Expected flattenable flag missing");
+            }
+            if (field.getName(cls.constant_pool).equals("x2")) {
+                checks ++;
+                if ((field.access_flags.flags & AccessFlags.ACC_FLATTENABLE) != 0)
+                    throw new AssertionError("Unexpected flattenable flag found");
+            }
+            if (field.getName(cls.constant_pool).equals("x3")) {
+                checks ++;
+                if ((field.access_flags.flags & AccessFlags.ACC_FLATTENABLE) == 0)
+                    throw new AssertionError("Expected flattenable flag missing");
+            }
+            if (field.getName(cls.constant_pool).equals("y1")) {
+                checks ++;
+                if ((field.access_flags.flags & AccessFlags.ACC_FLATTENABLE) != 0)
+                    throw new AssertionError("Unexpected flattenable flag found");
+            }
+            if (field.getName(cls.constant_pool).equals("y2")) {
+                checks ++;
+                if ((field.access_flags.flags & AccessFlags.ACC_FLATTENABLE) != 0)
+                    throw new AssertionError("Unexpected flattenable flag found");
+            }
+            if (field.getName(cls.constant_pool).equals("y3")) {
+                checks ++;
+                if ((field.access_flags.flags & AccessFlags.ACC_FLATTENABLE) == 0)
+                    throw new AssertionError("Expected flattenable flag missing");
+            }
+        }
+        if (checks != 6)
+            throw new AssertionError("Expected fields not found");
+    }
+}
--- a/test/langtools/tools/javac/valhalla/lworld-values/CheckNullCastable.out	Wed Mar 28 15:10:23 2018 +0200
+++ b/test/langtools/tools/javac/valhalla/lworld-values/CheckNullCastable.out	Mon Apr 02 17:50:51 2018 +0530
@@ -1,4 +1,4 @@
 CheckNullCastable.java:10:54: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: compiler.misc.type.null, CheckNullCastable)
-CheckNullCastable.java:11:17: compiler.err.incomparable.types: CheckNullCastable, compiler.misc.type.null
+CheckNullCastable.java:11:17: compiler.err.value.does.not.support: !=
 CheckNullCastable.java:12:18: compiler.err.incomparable.types: compiler.misc.type.null, CheckNullCastable
 3 errors
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/valhalla/lworld-values/DemoteToValueBasedTest.java	Mon Apr 02 17:50:51 2018 +0530
@@ -0,0 +1,11 @@
+/*
+ * @test /nodynamiccopyright/
+ * @summary Test that value classes get demoted to value based classes in -source 10 compiles.
+ * @compile Point.java
+ * @compile/fail/ref=DemoteToValueBasedTest.out -XDrawDiagnostics -XDdev DemoteToValueBasedTest.java
+ * @compile/fail/ref=DemoteToValueBasedTest10.out --should-stop:at=FLOW -Werror -XDrawDiagnostics -source 10 -XDdev DemoteToValueBasedTest.java
+ */
+
+public class DemoteToValueBasedTest {
+    Point p = null;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/valhalla/lworld-values/DemoteToValueBasedTest.out	Mon Apr 02 17:50:51 2018 +0530
@@ -0,0 +1,2 @@
+DemoteToValueBasedTest.java:10:15: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: compiler.misc.type.null, Point)
+1 error
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/valhalla/lworld-values/DemoteToValueBasedTest10.out	Mon Apr 02 17:50:51 2018 +0530
@@ -0,0 +1,5 @@
+- compiler.warn.source.no.bootclasspath: 10
+- compiler.err.warnings.and.werror
+DemoteToValueBasedTest.java:10:15: compiler.warn.suspicious.mix.of.null.with.value.based.class: Point
+1 error
+2 warnings
--- a/test/langtools/tools/javac/valhalla/lworld-values/FlattenableFlagTest.java	Wed Mar 28 15:10:23 2018 +0200
+++ b/test/langtools/tools/javac/valhalla/lworld-values/FlattenableFlagTest.java	Mon Apr 02 17:50:51 2018 +0530
@@ -42,7 +42,7 @@
     }
 
     __Flattenable Value v1;
-    Value v2;
+    __NotFlattened Value v2;
     __Flattenable Value v3;
   
     public static void main(String[] args) {
--- a/test/langtools/tools/javac/valhalla/lworld-values/Point.java	Wed Mar 28 15:10:23 2018 +0200
+++ b/test/langtools/tools/javac/valhalla/lworld-values/Point.java	Mon Apr 02 17:50:51 2018 +0530
@@ -31,7 +31,7 @@
  */
 
 final __ByValue class Point {
-    static final Point origin = makePoint(10, 20);
+    static final __NotFlattened Point origin = makePoint(10, 20);
     final int x;
     final int y;
     Point () {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/valhalla/lworld-values/ValueBasedWarningsTest.java	Mon Apr 02 17:50:51 2018 +0530
@@ -0,0 +1,17 @@
+/*
+ * @test /nodynamiccopyright/
+ * @summary Check that javac emits warnings rather than errors for null violation with value based classes.
+ * @compile/fail/ref=ValueBasedWarningsTest.out -Werror -XDrawDiagnostics -XDdev ValueBasedWarningsTest.java
+ */
+
+public class ValueBasedWarningsTest {
+    @ValueBased
+    final __ByValue class X {
+        final int x = 10;
+        void foo(X x1, X x2) {
+            x1 = null;
+            x2 = (X) null;
+            if (null instanceof X) {}
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/valhalla/lworld-values/ValueBasedWarningsTest.out	Mon Apr 02 17:50:51 2018 +0530
@@ -0,0 +1,6 @@
+ValueBasedWarningsTest.java:12:18: compiler.warn.suspicious.mix.of.null.with.value.based.class: ValueBasedWarningsTest.X
+ValueBasedWarningsTest.java:13:22: compiler.warn.suspicious.mix.of.null.with.value.based.class: ValueBasedWarningsTest.X
+ValueBasedWarningsTest.java:14:17: compiler.warn.suspicious.mix.of.null.with.value.based.class: ValueBasedWarningsTest.X
+- compiler.err.warnings.and.werror
+1 error
+3 warnings