--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java Mon Sep 09 11:43:16 2019 -0400
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java Wed Nov 27 09:00:01 2019 +0100
@@ -255,6 +255,41 @@
}
}
+ public boolean aliveAfter(Env<AttrContext> env, JCTree that, TreeMaker make) {
+ //we need to disable diagnostics temporarily; the problem is that if
+ //"that" contains e.g. an unreachable statement, an error
+ //message will be reported and will cause compilation to skip the flow analyis
+ //step - if we suppress diagnostics, we won't stop at Attr for flow-analysis
+ //related errors, which will allow for more errors to be detected
+ Log.DiagnosticHandler diagHandler = new Log.DiscardDiagnosticHandler(log);
+ try {
+ SnippetAliveAnalyzer analyzer = new SnippetAliveAnalyzer();
+
+ analyzer.analyzeTree(env, that, make);
+ return analyzer.isAlive();
+ } finally {
+ log.popDiagnosticHandler(diagHandler);
+ }
+ }
+
+ public boolean breaksOutOf(Env<AttrContext> env, JCTree loop, JCTree body, TreeMaker make) {
+ //we need to disable diagnostics temporarily; the problem is that if
+ //"that" contains e.g. an unreachable statement, an error
+ //message will be reported and will cause compilation to skip the flow analyis
+ //step - if we suppress diagnostics, we won't stop at Attr for flow-analysis
+ //related errors, which will allow for more errors to be detected
+ Log.DiagnosticHandler diagHandler = new Log.DiscardDiagnosticHandler(log);
+ try {
+ boolean[] breaksOut = new boolean[1];
+ SnippetBreakAnalyzer analyzer = new SnippetBreakAnalyzer(loop);
+
+ analyzer.analyzeTree(env, body, make);
+ return analyzer.breaksOut();
+ } finally {
+ log.popDiagnosticHandler(diagHandler);
+ }
+ }
+
/**
* Definite assignment scan mode
*/
@@ -1467,6 +1502,38 @@
}
/**
+ * Determine if alive after the given tree.
+ */
+ class SnippetAliveAnalyzer extends AliveAnalyzer {
+ @Override
+ public void visitClassDef(JCClassDecl tree) {
+ //skip
+ }
+ public boolean isAlive() {
+ return super.alive != Liveness.DEAD;
+ }
+ }
+
+ class SnippetBreakAnalyzer extends AliveAnalyzer {
+ private final JCTree loop;
+ private boolean breaksOut;
+
+ public SnippetBreakAnalyzer(JCTree loop) {
+ this.loop = loop;
+ }
+
+ @Override
+ public void visitBreak(JCBreak tree) {
+ breaksOut |= (super.alive == Liveness.ALIVE && tree.target == loop);
+ super.visitBreak(tree);
+ }
+
+ public boolean breaksOut() {
+ return breaksOut;
+ }
+ }
+
+ /**
* Specialized pass that performs DA/DU on a lambda
*/
class LambdaAssignAnalyzer extends AssignAnalyzer {