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

Print this page

        

*** 26,35 **** --- 26,37 ---- //todo: one might eliminate uninits.andSets when monotonic package com.sun.tools.javac.comp; import java.util.HashMap; + import java.util.Map; + import java.util.LinkedHashMap; import com.sun.tools.javac.code.*; import com.sun.tools.javac.tree.*; import com.sun.tools.javac.util.*; import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
*** 263,272 **** --- 265,278 ---- /** The list of exceptions that are either caught or declared to be * thrown. */ List<Type> caught; + /** The list of unreferenced automatic resources. + */ + Map<VarSymbol, JCVariableDecl> unrefdResources; + /** Set when processing a loop body the second time for DU analysis. */ boolean loopPassTwo = false; /*-------------------- Environments ----------------------*/
*** 961,970 **** --- 967,977 ---- } public void visitTry(JCTry tree) { List<Type> caughtPrev = caught; List<Type> thrownPrev = thrown; + Map<VarSymbol, JCVariableDecl> unrefdResourcesPrev = unrefdResources; thrown = List.nil(); for (List<JCCatch> l = tree.catchers; l.nonEmpty(); l = l.tail) { List<JCExpression> subClauses = TreeInfo.isMultiCatch(l.head) ? ((JCTypeDisjoint)l.head.param.vartype).components : List.of(l.head.param.vartype);
*** 975,994 **** --- 982,1035 ---- Bits uninitsTryPrev = uninitsTry; ListBuffer<PendingExit> prevPendingExits = pendingExits; pendingExits = new ListBuffer<PendingExit>(); Bits initsTry = inits.dup(); uninitsTry = uninits.dup(); + unrefdResources = new LinkedHashMap<VarSymbol, JCVariableDecl>(); + for (JCTree resource : tree.resources) { + if (resource instanceof JCVariableDecl) { + JCVariableDecl vdecl = (JCVariableDecl) resource; + visitVarDef(vdecl); + unrefdResources.put(vdecl.sym, vdecl); + } else if (resource instanceof JCExpression) { + scanExpr((JCExpression) resource); + } else { + throw new AssertionError(tree); // parser error + } + } + for (JCTree resource : tree.resources) { + MethodSymbol topCloseMethod = (MethodSymbol)syms.autoCloseableType.tsym.members().lookup(names.close).sym; + List<Type> closeableSupertypes = resource.type.isCompound() ? + types.interfaces(resource.type).prepend(types.supertype(resource.type)) : + List.of(resource.type); + for (Type sup : closeableSupertypes) { + if (types.asSuper(sup, syms.autoCloseableType.tsym) != null) { + MethodSymbol closeMethod = types.implementation(topCloseMethod, sup.tsym, types, true); + for (Type t : closeMethod.getThrownTypes()) { + markThrown(tree.body, t); + } + } + } + } 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.isEmpty() && + lint.isEnabled(Lint.LintCategory.ARM)) { + for (Map.Entry<VarSymbol, JCVariableDecl> e : unrefdResources.entrySet()) { + log.warning(e.getValue().pos(), + "automatic.resource.not.referenced", e.getKey()); + } + } + 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) ?
*** 1068,1077 **** --- 1109,1119 ---- ListBuffer<PendingExit> exits = pendingExits; pendingExits = prevPendingExits; while (exits.nonEmpty()) pendingExits.append(exits.next()); } uninitsTry.andSet(uninitsTryPrev).andSet(uninits); + unrefdResources = unrefdResourcesPrev; } public void visitConditional(JCConditional tree) { scanCond(tree.cond); Bits initsBeforeElse = initsWhenFalse;
*** 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() --- 1333,1352 ---- // 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.containsKey(sym)) { + unrefdResources.remove(sym); + } } public void visitTypeCast(JCTypeCast tree) { super.visitTypeCast(tree); if (!tree.type.isErroneous()