changeset 55912:0689af638ab6 switch2

Fixing crashes related to misplaced breaks.
author jlahoda
date Thu, 02 May 2019 09:58:09 +0200
parents 850fab702c3d
children ebdc3fee7ceb
files src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java src/jdk.compiler/share/classes/com/sun/tools/javac/util/Log.java test/langtools/tools/javac/switchexpr/WrongBreakTest.java test/langtools/tools/javac/switchexpr/WrongBreakTest.out
diffstat 4 files changed, 90 insertions(+), 29 deletions(-) [+]
line wrap: on
line diff
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java	Mon Apr 29 14:32:32 2019 +0200
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java	Thu May 02 09:58:09 2019 +0200
@@ -534,7 +534,8 @@
                 while (exits.nonEmpty()) {
                     PendingExit exit = exits.head;
                     exits = exits.tail;
-                    Assert.check(exit.tree.hasTag(RETURN));
+                    Assert.check(exit.tree.hasTag(RETURN) ||
+                                    log.hasErrorOn(exit.tree.pos()));
                 }
             } finally {
                 lint = lintPrev;
@@ -1053,7 +1054,8 @@
                     PendingExit exit = exits.head;
                     exits = exits.tail;
                     if (!(exit instanceof ThrownPendingExit)) {
-                        Assert.check(exit.tree.hasTag(RETURN));
+                        Assert.check(exit.tree.hasTag(RETURN) ||
+                                         log.hasErrorOn(exit.tree.pos()));
                     } else {
                         // uncaught throws will be reported later
                         pendingExits.append(exit);
@@ -1385,7 +1387,8 @@
                     PendingExit exit = exits.head;
                     exits = exits.tail;
                     if (!(exit instanceof ThrownPendingExit)) {
-                        Assert.check(exit.tree.hasTag(RETURN));
+                        Assert.check(exit.tree.hasTag(RETURN) ||
+                                        log.hasErrorOn(exit.tree.pos()));
                     } else {
                         // uncaught throws will be reported later
                         pendingExits.append(exit);
@@ -2005,7 +2008,9 @@
                     while (exits.nonEmpty()) {
                         PendingExit exit = exits.head;
                         exits = exits.tail;
-                        Assert.check(exit.tree.hasTag(RETURN), exit.tree);
+                        Assert.check(exit.tree.hasTag(RETURN) ||
+                                         log.hasErrorOn(exit.tree.pos()),
+                                     exit.tree);
                         if (isInitialConstructor) {
                             Assert.check(exit instanceof AssignPendingExit);
                             inits.assign(((AssignPendingExit) exit).exit_inits);
@@ -2434,33 +2439,32 @@
         
         @Override
         public void visitBreakWith(JCBreakWith tree) {
-            if (tree.target.hasTag(SWITCH_EXPRESSION)) {
-                JCSwitchExpression expr = (JCSwitchExpression) tree.target;
-                if (expr.type.hasTag(BOOLEAN)) {
-                    scanCond(tree.value);
-                    Bits initsAfterBreakWhenTrue = new Bits(initsWhenTrue);
-                    Bits initsAfterBreakWhenFalse = new Bits(initsWhenFalse);
-                    Bits uninitsAfterBreakWhenTrue = new Bits(uninitsWhenTrue);
-                    Bits uninitsAfterBreakWhenFalse = new Bits(uninitsWhenFalse);
-                    PendingExit exit = new PendingExit(tree) {
-                        @Override
-                        void resolveJump() {
-                            if (!inits.isReset()) {
-                                split(true);
-                            }
-                            initsWhenTrue.andSet(initsAfterBreakWhenTrue);
-                            initsWhenFalse.andSet(initsAfterBreakWhenFalse);
-                            uninitsWhenTrue.andSet(uninitsAfterBreakWhenTrue);
-                            uninitsWhenFalse.andSet(uninitsAfterBreakWhenFalse);
+            JCSwitchExpression expr = (JCSwitchExpression) tree.target;
+            if (expr != null && expr.type.hasTag(BOOLEAN)) {
+                scanCond(tree.value);
+                Bits initsAfterBreakWhenTrue = new Bits(initsWhenTrue);
+                Bits initsAfterBreakWhenFalse = new Bits(initsWhenFalse);
+                Bits uninitsAfterBreakWhenTrue = new Bits(uninitsWhenTrue);
+                Bits uninitsAfterBreakWhenFalse = new Bits(uninitsWhenFalse);
+                PendingExit exit = new PendingExit(tree) {
+                    @Override
+                    void resolveJump() {
+                        if (!inits.isReset()) {
+                            split(true);
                         }
-                    };
-                    merge();
-                    recordExit(exit);
-                    return ;
-                }
+                        initsWhenTrue.andSet(initsAfterBreakWhenTrue);
+                        initsWhenFalse.andSet(initsAfterBreakWhenFalse);
+                        uninitsWhenTrue.andSet(uninitsAfterBreakWhenTrue);
+                        uninitsWhenFalse.andSet(uninitsAfterBreakWhenFalse);
+                    }
+                };
+                merge();
+                recordExit(exit);
+                return ;
+            } else {
+                scan(tree.value);
+                recordExit(new AssignPendingExit(tree, inits, uninits));
             }
-            scan(tree.value);
-            recordExit(new AssignPendingExit(tree, inits, uninits));
         }
 
         @Override
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Log.java	Mon Apr 29 14:32:32 2019 +0200
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Log.java	Thu May 02 09:58:09 2019 +0200
@@ -554,6 +554,13 @@
             }
         }
 
+    /**Is an error reported at the given pos (inside the current source)?*/
+    public boolean hasErrorOn(DiagnosticPosition pos) {
+        JavaFileObject file = source != null ? source.fileObject : null;
+
+        return file != null && recorded.contains(new Pair<>(file, pos.getPreferredPosition()));
+    }
+
     /** Prompt user after an error.
      */
     public void prompt() {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/switchexpr/WrongBreakTest.java	Thu May 02 09:58:09 2019 +0200
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2019, 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
+ * @bug 8222750
+ * @summary Ensure javac is not crashing for wrong breaks.
+ * @compile/fail/ref=WrongBreakTest.out --enable-preview -source ${jdk.version} -XDrawDiagnostics -XDshould-stop.at=FLOW WrongBreakTest.java
+ */
+
+public class WrongBreakTest {
+
+    void test(int i) {
+        int s = 0;
+        int j = switch (s) { default: break; };
+        test(switch (s) { default: break-with; });
+        while (true) {
+            break-with 15;
+        }
+    }
+
+    void test(Object o) {}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/switchexpr/WrongBreakTest.out	Thu May 02 09:58:09 2019 +0200
@@ -0,0 +1,7 @@
+WrongBreakTest.java:36:46: compiler.err.illegal.start.of.expr
+WrongBreakTest.java:35:39: compiler.err.break.outside.switch.loop
+WrongBreakTest.java:36:9: compiler.err.ref.ambiguous: test, kindname.method, test(int), WrongBreakTest, kindname.method, test(java.lang.Object), WrongBreakTest
+WrongBreakTest.java:38:13: compiler.err.break.complex.value.no.switch.expression
+- compiler.note.preview.filename: WrongBreakTest.java
+- compiler.note.preview.recompile
+4 errors