--- 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) {