src/share/classes/com/sun/tools/javac/comp/Flow.java

Print this page

        

*** 263,272 **** --- 263,276 ---- /** The list of exceptions that are either caught or declared to be * thrown. */ List<Type> caught; + /** The list of unreferenced automatic resources. + */ + List<Symbol> unrefdResources; + /** Set when processing a loop body the second time for DU analysis. */ boolean loopPassTwo = false; /*-------------------- Environments ----------------------*/
*** 959,968 **** --- 963,982 ---- } } } 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<Type> caughtPrev = caught; List<Type> thrownPrev = thrown; thrown = List.nil(); for (List<JCCatch> l = tree.catchers; l.nonEmpty(); l = l.tail) { List<JCExpression> subClauses = TreeInfo.isMultiCatch(l.head) ?
*** 975,994 **** --- 989,1028 ---- Bits uninitsTryPrev = uninitsTry; ListBuffer<PendingExit> prevPendingExits = pendingExits; pendingExits = new ListBuffer<PendingExit>(); 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<Type> thrownInTry = thrown; thrown = thrownPrev; caught = caughtPrev; boolean aliveEnd = alive; uninitsTry.andSet(uninits); Bits initsEnd = inits; Bits uninitsEnd = uninits; int nextadrCatch = nextadr; + if (unrefdResources.nonEmpty()) { + for (List<JCTree> 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<Type> caughtInTry = List.nil(); for (List<JCCatch> l = tree.catchers; l.nonEmpty(); l = l.tail) { alive = true; JCVariableDecl param = l.head.param; List<JCExpression> subClauses = TreeInfo.isMultiCatch(l.head) ?
*** 1291,1302 **** // annotations don't get scanned tree.underlyingType.accept(this); } public void visitIdent(JCIdent tree) { ! if (tree.sym.kind == VAR) checkInit(tree.pos(), (VarSymbol)tree.sym); } public void visitTypeCast(JCTypeCast tree) { super.visitTypeCast(tree); if (!tree.type.isErroneous() --- 1325,1348 ---- // annotations don't get scanned tree.underlyingType.accept(this); } public void visitIdent(JCIdent tree) { ! 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<Symbol> lb = new ListBuffer<Symbol>(); + for (List<Symbol> l = unrefdResources; l.nonEmpty(); l = l.tail) + if (l.head != sym) + lb.add(l.head); + unrefdResources = lb.toList(); + } } public void visitTypeCast(JCTypeCast tree) { super.visitTypeCast(tree); if (!tree.type.isErroneous()