--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java Fri Aug 16 10:32:42 2013 +0100
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java Thu Aug 15 22:33:43 2013 +0200
@@ -224,7 +224,7 @@
}
try {
new AliveAnalyzer().analyzeTree(env, that, make);
- new FlowAnalyzer().analyzeTree(env, that, make);
+ new LambdaFlowAnalyzer().analyzeTree(env, that, make);
} finally {
if (!speculative) {
log.popDiagnosticHandler(diagHandler);
@@ -1259,12 +1259,24 @@
ListBuffer<FlowPendingExit> prevPending = pendingExits;
try {
pendingExits = ListBuffer.lb();
- caught = List.of(syms.throwableType); //inhibit exception checking
+ caught = tree.getDescriptorType(types).getThrownTypes();
thrown = List.nil();
scan(tree.body);
- tree.inferredThrownTypes = thrown;
- }
- finally {
+ List<FlowPendingExit> exits = pendingExits.toList();
+ pendingExits = new ListBuffer<FlowPendingExit>();
+ while (exits.nonEmpty()) {
+ FlowPendingExit exit = exits.head;
+ exits = exits.tail;
+ if (exit.thrown == null) {
+ Assert.check(exit.tree.hasTag(RETURN));
+ } else {
+ // uncaught throws will be reported later
+ pendingExits.append(exit);
+ }
+ }
+
+ errorUncaught();
+ } finally {
pendingExits = prevPending;
caught = prevCaught;
thrown = prevThrown;
@@ -1303,6 +1315,33 @@
}
/**
+ * Specialized pass that performs inference of thrown types for lambdas.
+ */
+ class LambdaFlowAnalyzer extends FlowAnalyzer {
+ @Override
+ public void visitLambda(JCLambda tree) {
+ if (tree.type != null &&
+ tree.type.isErroneous()) {
+ return;
+ }
+ List<Type> prevCaught = caught;
+ List<Type> prevThrown = thrown;
+ ListBuffer<FlowPendingExit> prevPending = pendingExits;
+ try {
+ pendingExits = ListBuffer.lb();
+ caught = List.of(syms.throwableType);
+ thrown = List.nil();
+ scan(tree.body);
+ tree.inferredThrownTypes = thrown;
+ } finally {
+ pendingExits = prevPending;
+ caught = prevCaught;
+ thrown = prevThrown;
+ }
+ }
+ }
+
+ /**
* This pass implements (i) definite assignment analysis, which ensures that
* each variable is assigned when used and (ii) definite unassignment analysis,
* which ensures that no final variable is assigned more than once. This visitor