langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java
changeset 6148 3a8158299c51
parent 5847 1908176fd6e3
child 6151 dd513881e71d
equal deleted inserted replaced
6147:0074061d0efd 6148:3a8158299c51
    26 //todo: one might eliminate uninits.andSets when monotonic
    26 //todo: one might eliminate uninits.andSets when monotonic
    27 
    27 
    28 package com.sun.tools.javac.comp;
    28 package com.sun.tools.javac.comp;
    29 
    29 
    30 import java.util.HashMap;
    30 import java.util.HashMap;
       
    31 import java.util.Map;
       
    32 import java.util.LinkedHashMap;
    31 
    33 
    32 import com.sun.tools.javac.code.*;
    34 import com.sun.tools.javac.code.*;
    33 import com.sun.tools.javac.tree.*;
    35 import com.sun.tools.javac.tree.*;
    34 import com.sun.tools.javac.util.*;
    36 import com.sun.tools.javac.util.*;
    35 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
    37 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
   263     /** The list of exceptions that are either caught or declared to be
   265     /** The list of exceptions that are either caught or declared to be
   264      *  thrown.
   266      *  thrown.
   265      */
   267      */
   266     List<Type> caught;
   268     List<Type> caught;
   267 
   269 
       
   270     /** The list of unreferenced automatic resources.
       
   271      */
       
   272     Map<VarSymbol, JCVariableDecl> unrefdResources;
       
   273 
   268     /** Set when processing a loop body the second time for DU analysis. */
   274     /** Set when processing a loop body the second time for DU analysis. */
   269     boolean loopPassTwo = false;
   275     boolean loopPassTwo = false;
   270 
   276 
   271     /*-------------------- Environments ----------------------*/
   277     /*-------------------- Environments ----------------------*/
   272 
   278 
   961         }
   967         }
   962 
   968 
   963     public void visitTry(JCTry tree) {
   969     public void visitTry(JCTry tree) {
   964         List<Type> caughtPrev = caught;
   970         List<Type> caughtPrev = caught;
   965         List<Type> thrownPrev = thrown;
   971         List<Type> thrownPrev = thrown;
       
   972         Map<VarSymbol, JCVariableDecl> unrefdResourcesPrev = unrefdResources;
   966         thrown = List.nil();
   973         thrown = List.nil();
   967         for (List<JCCatch> l = tree.catchers; l.nonEmpty(); l = l.tail) {
   974         for (List<JCCatch> l = tree.catchers; l.nonEmpty(); l = l.tail) {
   968             List<JCExpression> subClauses = TreeInfo.isMultiCatch(l.head) ?
   975             List<JCExpression> subClauses = TreeInfo.isMultiCatch(l.head) ?
   969                     ((JCTypeDisjoint)l.head.param.vartype).components :
   976                     ((JCTypeDisjoint)l.head.param.vartype).components :
   970                     List.of(l.head.param.vartype);
   977                     List.of(l.head.param.vartype);
   975         Bits uninitsTryPrev = uninitsTry;
   982         Bits uninitsTryPrev = uninitsTry;
   976         ListBuffer<PendingExit> prevPendingExits = pendingExits;
   983         ListBuffer<PendingExit> prevPendingExits = pendingExits;
   977         pendingExits = new ListBuffer<PendingExit>();
   984         pendingExits = new ListBuffer<PendingExit>();
   978         Bits initsTry = inits.dup();
   985         Bits initsTry = inits.dup();
   979         uninitsTry = uninits.dup();
   986         uninitsTry = uninits.dup();
       
   987         unrefdResources = new LinkedHashMap<VarSymbol, JCVariableDecl>();
       
   988         for (JCTree resource : tree.resources) {
       
   989             if (resource instanceof JCVariableDecl) {
       
   990                 JCVariableDecl vdecl = (JCVariableDecl) resource;
       
   991                 visitVarDef(vdecl);
       
   992                 unrefdResources.put(vdecl.sym, vdecl);
       
   993             } else if (resource instanceof JCExpression) {
       
   994                 scanExpr((JCExpression) resource);
       
   995             } else {
       
   996                 throw new AssertionError(tree);  // parser error
       
   997             }
       
   998         }
       
   999         for (JCTree resource : tree.resources) {
       
  1000             MethodSymbol topCloseMethod = (MethodSymbol)syms.autoCloseableType.tsym.members().lookup(names.close).sym;
       
  1001             List<Type> closeableSupertypes = resource.type.isCompound() ?
       
  1002                 types.interfaces(resource.type).prepend(types.supertype(resource.type)) :
       
  1003                 List.of(resource.type);
       
  1004             for (Type sup : closeableSupertypes) {
       
  1005                 if (types.asSuper(sup, syms.autoCloseableType.tsym) != null) {
       
  1006                     MethodSymbol closeMethod = types.implementation(topCloseMethod, sup.tsym, types, true);
       
  1007                     for (Type t : closeMethod.getThrownTypes()) {
       
  1008                         markThrown(tree.body, t);
       
  1009                     }
       
  1010                 }
       
  1011             }
       
  1012         }
   980         scanStat(tree.body);
  1013         scanStat(tree.body);
   981         List<Type> thrownInTry = thrown;
  1014         List<Type> thrownInTry = thrown;
   982         thrown = thrownPrev;
  1015         thrown = thrownPrev;
   983         caught = caughtPrev;
  1016         caught = caughtPrev;
   984         boolean aliveEnd = alive;
  1017         boolean aliveEnd = alive;
   985         uninitsTry.andSet(uninits);
  1018         uninitsTry.andSet(uninits);
   986         Bits initsEnd = inits;
  1019         Bits initsEnd = inits;
   987         Bits uninitsEnd = uninits;
  1020         Bits uninitsEnd = uninits;
   988         int nextadrCatch = nextadr;
  1021         int nextadrCatch = nextadr;
       
  1022 
       
  1023         if (!unrefdResources.isEmpty() &&
       
  1024                 lint.isEnabled(Lint.LintCategory.ARM)) {
       
  1025             for (Map.Entry<VarSymbol, JCVariableDecl> e : unrefdResources.entrySet()) {
       
  1026                 log.warning(e.getValue().pos(),
       
  1027                             "automatic.resource.not.referenced", e.getKey());
       
  1028             }
       
  1029         }
   989 
  1030 
   990         List<Type> caughtInTry = List.nil();
  1031         List<Type> caughtInTry = List.nil();
   991         for (List<JCCatch> l = tree.catchers; l.nonEmpty(); l = l.tail) {
  1032         for (List<JCCatch> l = tree.catchers; l.nonEmpty(); l = l.tail) {
   992             alive = true;
  1033             alive = true;
   993             JCVariableDecl param = l.head.param;
  1034             JCVariableDecl param = l.head.param;
  1068             ListBuffer<PendingExit> exits = pendingExits;
  1109             ListBuffer<PendingExit> exits = pendingExits;
  1069             pendingExits = prevPendingExits;
  1110             pendingExits = prevPendingExits;
  1070             while (exits.nonEmpty()) pendingExits.append(exits.next());
  1111             while (exits.nonEmpty()) pendingExits.append(exits.next());
  1071         }
  1112         }
  1072         uninitsTry.andSet(uninitsTryPrev).andSet(uninits);
  1113         uninitsTry.andSet(uninitsTryPrev).andSet(uninits);
       
  1114         unrefdResources = unrefdResourcesPrev;
  1073     }
  1115     }
  1074 
  1116 
  1075     public void visitConditional(JCConditional tree) {
  1117     public void visitConditional(JCConditional tree) {
  1076         scanCond(tree.cond);
  1118         scanCond(tree.cond);
  1077         Bits initsBeforeElse = initsWhenFalse;
  1119         Bits initsBeforeElse = initsWhenFalse;
  1291         // annotations don't get scanned
  1333         // annotations don't get scanned
  1292         tree.underlyingType.accept(this);
  1334         tree.underlyingType.accept(this);
  1293     }
  1335     }
  1294 
  1336 
  1295     public void visitIdent(JCIdent tree) {
  1337     public void visitIdent(JCIdent tree) {
  1296         if (tree.sym.kind == VAR)
  1338         if (tree.sym.kind == VAR) {
  1297             checkInit(tree.pos(), (VarSymbol)tree.sym);
  1339             checkInit(tree.pos(), (VarSymbol)tree.sym);
       
  1340             referenced(tree.sym);
       
  1341         }
       
  1342     }
       
  1343 
       
  1344     void referenced(Symbol sym) {
       
  1345         if (unrefdResources != null && unrefdResources.containsKey(sym)) {
       
  1346             unrefdResources.remove(sym);
       
  1347         }
  1298     }
  1348     }
  1299 
  1349 
  1300     public void visitTypeCast(JCTypeCast tree) {
  1350     public void visitTypeCast(JCTypeCast tree) {
  1301         super.visitTypeCast(tree);
  1351         super.visitTypeCast(tree);
  1302         if (!tree.type.isErroneous()
  1352         if (!tree.type.isErroneous()