--- old/src/share/classes/com/sun/tools/javac/comp/Flow.java 2010-06-30 14:15:14.000000000 -0700 +++ new/src/share/classes/com/sun/tools/javac/comp/Flow.java 2010-06-30 14:15:14.000000000 -0700 @@ -265,6 +265,10 @@ */ List caught; + /** The list of unreferenced automatic resources. + */ + List unrefdResources; + /** Set when processing a loop body the second time for DU analysis. */ boolean loopPassTwo = false; @@ -961,6 +965,16 @@ } public void visitTry(JCTry tree) { + unrefdResources = List.nil(); + for (JCTree resource : tree.resources) { + if (resource instanceof JCVariableDecl) { + visitVarDef((JCVariableDecl) resource); + } else if (resource instanceof JCExpression) { + scanExpr((JCExpression) resource); + } else { + throw new AssertionError(tree); // parser error + } + } List caughtPrev = caught; List thrownPrev = thrown; thrown = List.nil(); @@ -977,6 +991,14 @@ pendingExits = new ListBuffer(); Bits initsTry = inits.dup(); uninitsTry = uninits.dup(); + for (JCTree resource : tree.resources) { + MethodSymbol topCloseMethod = (MethodSymbol)syms.autoCloseableType.tsym.members().lookup(names.close).sym; + MethodSymbol closeMethod = types.implementation(topCloseMethod, resource.type.tsym, types, true); + + for (Type thrownType : closeMethod.getThrownTypes()) { + markThrown(tree.body, thrownType); + } + } scanStat(tree.body); List thrownInTry = thrown; thrown = thrownPrev; @@ -987,6 +1009,18 @@ Bits uninitsEnd = uninits; int nextadrCatch = nextadr; + if (unrefdResources.nonEmpty()) { + for (List l = tree.resources; l.nonEmpty(); l = l.tail) { + if (l.head instanceof JCVariableDecl) { + JCVariableDecl v = (JCVariableDecl) l.head; + if (unrefdResources.contains(v.sym)) { + log.warning(v.pos(), + "automatic.resource.not.referenced", v.sym); + } + } + } + } + List caughtInTry = List.nil(); for (List l = tree.catchers; l.nonEmpty(); l = l.tail) { alive = true; @@ -1293,8 +1327,20 @@ } public void visitIdent(JCIdent tree) { - if (tree.sym.kind == VAR) + if (tree.sym.kind == VAR) { checkInit(tree.pos(), (VarSymbol)tree.sym); + referenced(tree.sym); + } + } + + void referenced(Symbol sym) { + if (unrefdResources != null && unrefdResources.contains(sym)) { + ListBuffer lb = new ListBuffer(); + for (List l = unrefdResources; l.nonEmpty(); l = l.tail) + if (l.head != sym) + lb.add(l.head); + unrefdResources = lb.toList(); + } } public void visitTypeCast(JCTypeCast tree) {