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()