src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java
changeset 55306 ea43db53de91
parent 54321 c9a492ad1aed
child 59285 7799a51dbe30
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java	Sun Jun 09 15:48:57 2019 -0700
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java	Mon Jun 10 05:09:52 2019 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 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
@@ -314,6 +314,12 @@
                 JCTree getTarget(JCTree tree) {
                     return ((JCContinue)tree).target;
                 }
+            },
+            YIELD(JCTree.Tag.YIELD) {
+                @Override
+                JCTree getTarget(JCTree tree) {
+                    return ((JCYield)tree).target;
+                }
             };
 
             final JCTree.Tag treeTag;
@@ -386,6 +392,11 @@
             return resolveJump(tree, oldPendingExits, JumpKind.BREAK);
         }
 
+        /** Resolve all yields of this statement. */
+        Liveness resolveYields(JCTree tree, ListBuffer<PendingExit> oldPendingExits) {
+            return resolveJump(tree, oldPendingExits, JumpKind.YIELD);
+        }
+
         @Override
         public void scan(JCTree tree) {
             if (tree != null && (
@@ -400,9 +411,15 @@
         }
 
         protected void scanSyntheticBreak(TreeMaker make, JCTree swtch) {
-            JCBreak brk = make.at(Position.NOPOS).Break(null);
-            brk.target = swtch;
-            scan(brk);
+            if (swtch.hasTag(SWITCH_EXPRESSION)) {
+                JCYield brk = make.at(Position.NOPOS).Yield(null);
+                brk.target = swtch;
+                scan(brk);
+            } else {
+                JCBreak brk = make.at(Position.NOPOS).Break(null);
+                brk.target = swtch;
+                scan(brk);
+            }
         }
     }
 
@@ -517,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;
@@ -677,7 +695,7 @@
                 log.error(tree, Errors.NotExhaustive);
             }
             alive = prevAlive;
-            alive = alive.or(resolveBreaks(tree, prevPendingExits));
+            alive = alive.or(resolveYields(tree, prevPendingExits));
         }
 
         public void visitTry(JCTry tree) {
@@ -745,8 +763,12 @@
         }
 
         public void visitBreak(JCBreak tree) {
-            if (tree.isValueBreak())
-                scan(tree.value);
+            recordExit(new PendingExit(tree));
+        }
+
+        @Override
+        public void visitYield(JCYield tree) {
+            scan(tree.value);
             recordExit(new PendingExit(tree));
         }
 
@@ -1032,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);
@@ -1126,7 +1149,11 @@
                 scan(c.pats);
                 scan(c.stats);
             }
-            resolveBreaks(tree, prevPendingExits);
+            if (tree.hasTag(SWITCH_EXPRESSION)) {
+                resolveYields(tree, prevPendingExits);
+            } else {
+                resolveBreaks(tree, prevPendingExits);
+            }
         }
 
         public void visitTry(JCTry tree) {
@@ -1267,8 +1294,11 @@
             }
 
         public void visitBreak(JCBreak tree) {
-            if (tree.isValueBreak())
-                scan(tree.value);
+            recordExit(new PendingExit(tree));
+        }
+
+        public void visitYield(JCYield tree) {
+            scan(tree.value);
             recordExit(new PendingExit(tree));
         }
 
@@ -1357,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);
@@ -1977,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);
@@ -2232,7 +2265,11 @@
                     inits.andSet(initsSwitch);
                 }
             }
-            resolveBreaks(tree, prevPendingExits);
+            if (tree.hasTag(SWITCH_EXPRESSION)) {
+                resolveYields(tree, prevPendingExits);
+            } else {
+                resolveBreaks(tree, prevPendingExits);
+            }
             nextadr = nextadrPrev;
         }
         // where
@@ -2397,35 +2434,37 @@
 
         @Override
         public void visitBreak(JCBreak tree) {
-            if (tree.isValueBreak()) {
-                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);
-                            }
-                        };
-                        merge();
-                        recordExit(exit);
-                        return ;
+            recordExit(new AssignPendingExit(tree, inits, uninits));
+        }
+
+        @Override
+        public void visitYield(JCYield tree) {
+            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);
+                        }
+                        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));
             }
-            recordExit(new AssignPendingExit(tree, inits, uninits));
         }
 
         @Override
@@ -2788,9 +2827,8 @@
         }
 
         @Override
-        public void visitBreak(JCBreak tree) {
-            if (tree.isValueBreak())
-                scan(tree.value);
+        public void visitYield(JCYield tree) {
+            scan(tree.value);
         }
 
         public void visitModuleDef(JCModuleDecl tree) {