changeset 51541:36a1c43285a6 switch

Various bugfixes for problems reported by mcimadamore and gbierman.
author jlahoda
date Tue, 10 Jul 2018 10:56:51 +0200
parents 10a0cdfd83ad
children 1b687dc837a3
files src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TransTypes.java src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties test/langtools/tools/javac/switchexpr/ExpressionSwitchCodeFromJLS.java test/langtools/tools/javac/switchexpr/ExpressionSwitchDA.java test/langtools/tools/javac/switchexpr/ExpressionSwitchIntersectionTypes.java
diffstat 6 files changed, 101 insertions(+), 16 deletions(-) [+]
line wrap: on
line diff
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java	Mon Jul 09 15:02:42 2018 +0100
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java	Tue Jul 10 10:56:51 2018 +0200
@@ -217,7 +217,7 @@
 
     public void analyzeTree(Env<AttrContext> env, TreeMaker make) {
         new AliveAnalyzer().analyzeTree(env, make);
-        new AssignAnalyzer().analyzeTree(env);
+        new AssignAnalyzer().analyzeTree(env, make);
         new FlowAnalyzer().analyzeTree(env, make);
         new CaptureAnalyzer().analyzeTree(env, make);
     }
@@ -250,7 +250,7 @@
         //related errors, which will allow for more errors to be detected
         Log.DiagnosticHandler diagHandler = new Log.DiscardDiagnosticHandler(log);
         try {
-            new LambdaAssignAnalyzer(env).analyzeTree(env, that);
+            new LambdaAssignAnalyzer(env).analyzeTree(env, that, make);
             LambdaFlowAnalyzer flowAnalyzer = new LambdaFlowAnalyzer();
             flowAnalyzer.analyzeTree(env, that, make);
             return flowAnalyzer.inferredThrownTypes;
@@ -405,6 +405,12 @@
         public void visitPackageDef(JCPackageDecl tree) {
             // Do nothing for PackageDecl
         }
+
+        protected void scanSyntheticBreak(TreeMaker make, JCTree swtch) {
+            JCBreak brk = make.at(Position.NOPOS).Break(null);
+            brk.target = swtch;
+            scan(brk);
+        }
     }
 
     /**
@@ -614,8 +620,12 @@
                 }
                 scanStats(c.stats);
                 c.completesNormally = alive;
+                if (alive && c.caseKind == CaseKind.RULE) {
+                    scanSyntheticBreak(make, tree);
+                    alive = false;
+                }
                 // Warn about fall-through if lint switch fallthrough enabled.
-                if (alive && c.caseKind == CaseKind.STATEMENT &&
+                if (alive &&
                     lint.isEnabled(Lint.LintCategory.FALLTHROUGH) &&
                     c.stats.nonEmpty() && l.tail.nonEmpty())
                     log.warning(Lint.LintCategory.FALLTHROUGH,
@@ -2203,6 +2213,9 @@
                     uninits.assign(uninits.andSet(uninitsSwitch));
                 }
                 scan(c.stats);
+                if (c.completesNormally && c.caseKind == CaseKind.RULE) {
+                    scanSyntheticBreak(make, tree);
+                }
                 addVars(c.stats, initsSwitch, uninitsSwitch);
                 if (!hasDefault) {
                     inits.assign(initsSwitch);
@@ -2559,11 +2572,11 @@
 
         /** Perform definite assignment/unassignment analysis on a tree.
          */
-        public void analyzeTree(Env<?> env) {
-            analyzeTree(env, env.tree);
+        public void analyzeTree(Env<?> env, TreeMaker make) {
+            analyzeTree(env, env.tree, make);
          }
 
-        public void analyzeTree(Env<?> env, JCTree tree) {
+        public void analyzeTree(Env<?> env, JCTree tree, TreeMaker make) {
             try {
                 startPos = tree.pos().getStartPosition();
 
@@ -2574,6 +2587,7 @@
                         vardecls[i] = null;
                 firstadr = 0;
                 nextadr = 0;
+                Flow.this.make = make;
                 pendingExits = new ListBuffer<>();
                 this.classDef = null;
                 unrefdResources = WriteableScope.create(env.enclClass.sym);
@@ -2589,6 +2603,7 @@
                 }
                 firstadr = 0;
                 nextadr = 0;
+                Flow.this.make = null;
                 pendingExits = null;
                 this.classDef = null;
                 unrefdResources = null;
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TransTypes.java	Mon Jul 09 15:02:42 2018 +0100
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TransTypes.java	Tue Jul 10 10:56:51 2018 +0200
@@ -574,7 +574,8 @@
         Type target = enumSwitch ? erasure(tree.selector.type) : syms.intType;
         tree.selector = translate(tree.selector, target);
         tree.cases = translate(tree.cases);
-        result = tree;
+        tree.type = erasure(tree.type);
+        result = retype(tree, tree.type, pt);
     }
 
     public void visitSynchronized(JCSynchronized tree) {
@@ -619,8 +620,11 @@
 
     @Override
     public void visitBreak(JCBreak tree) {
-        if (tree.isValueBreak())
+        if (tree.isValueBreak()) {
             tree.value = translate(tree.value, erasure(tree.value.type));
+            tree.value.type = erasure(tree.value.type);
+            tree.value = retype(tree.value, tree.value.type, pt);
+        }
         result = tree;
     }
 
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties	Mon Jul 09 15:02:42 2018 +0100
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties	Tue Jul 10 10:56:51 2018 +0200
@@ -207,7 +207,7 @@
     expression break not immediately enclosed by a switch expression
 
 compiler.err.break.complex.value.no.switch.expression=\
-    complex value in break outside of switch expression
+    value break outside of switch expression
 
 # 0: name
 compiler.err.call.must.be.first.stmt.in.ctor=\
--- a/test/langtools/tools/javac/switchexpr/ExpressionSwitchCodeFromJLS.java	Mon Jul 09 15:02:42 2018 +0100
+++ b/test/langtools/tools/javac/switchexpr/ExpressionSwitchCodeFromJLS.java	Tue Jul 10 10:56:51 2018 +0200
@@ -4,9 +4,7 @@
  *
  * 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.
+ * 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
--- a/test/langtools/tools/javac/switchexpr/ExpressionSwitchDA.java	Mon Jul 09 15:02:42 2018 +0100
+++ b/test/langtools/tools/javac/switchexpr/ExpressionSwitchDA.java	Tue Jul 10 10:56:51 2018 +0200
@@ -4,9 +4,7 @@
  *
  * 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.
+ * 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
@@ -102,7 +100,6 @@
         }
         System.out.println(i);
     }
-    // These two should pass but fail :-( Bug in reachability
     public static void test9() {
         int i;
         int j = 0;
@@ -157,6 +154,15 @@
         }
         System.out.println(i);
     }
+    public static void test15() {
+        final int i;
+        int j = 0;
+        switch (j) {
+            case 0 -> { i=42; }
+            default -> { i=42; }
+        }
+        System.out.println(i);
+    }
     public static void main(String[] args) {
         test1();
         test2();
@@ -172,5 +178,6 @@
         test12();
         test13();
         test14();
+        test15();
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/switchexpr/ExpressionSwitchIntersectionTypes.java	Tue Jul 10 10:56:51 2018 +0200
@@ -0,0 +1,61 @@
+/*
+ * 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.
+ */
+
+/**
+ * @test
+ * @compile --enable-preview -source 12 ExpressionSwitchIntersectionTypes.java
+ * @run main/othervm --enable-preview ExpressionSwitchIntersectionTypes
+ */
+
+public class ExpressionSwitchIntersectionTypes<X  extends java.io.Serializable & Runnable> {
+
+    void test1(int i, X x) {
+        Runnable r1 = switch (i) {
+            default -> x;
+        };
+        r1.run();
+    }
+
+    void test2(int i, X x) {
+        (switch (i) {
+            default -> x;
+        }).run();
+    }
+
+    public static void main(String[] args) {
+        ExpressionSwitchIntersectionTypes t = new ExpressionSwitchIntersectionTypes();
+        try {
+            t.test1(0, "");
+            throw new AssertionError("Expected exception didn't occur.");
+        } catch (ClassCastException ex) {
+            //good
+        }
+        try {
+            t.test2(0, "");
+            throw new AssertionError("Expected exception didn't occur.");
+        } catch (ClassCastException ex) {
+            //good
+        }
+    }
+
+}