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

Print this page




 248      */
 249     JCClassDecl classDef;
 250 
 251     /** The first variable sequence number in this class definition.
 252      */
 253     int firstadr;
 254 
 255     /** The next available variable sequence number.
 256      */
 257     int nextadr;
 258 
 259     /** The list of possibly thrown declarable exceptions.
 260      */
 261     List<Type> thrown;
 262 
 263     /** The list of exceptions that are either caught or declared to be
 264      *  thrown.
 265      */
 266     List<Type> caught;
 267 




 268     /** Set when processing a loop body the second time for DU analysis. */
 269     boolean loopPassTwo = false;
 270 
 271     /*-------------------- Environments ----------------------*/
 272 
 273     /** A pending exit.  These are the statements return, break, and
 274      *  continue.  In addition, exception-throwing expressions or
 275      *  statements are put here when not known to be caught.  This
 276      *  will typically result in an error unless it is within a
 277      *  try-finally whose finally block cannot complete normally.
 278      */
 279     static class PendingExit {
 280         JCTree tree;
 281         Bits inits;
 282         Bits uninits;
 283         Type thrown;
 284         PendingExit(JCTree tree, Bits inits, Bits uninits) {
 285             this.tree = tree;
 286             this.inits = inits.dup();
 287             this.uninits = uninits.dup();


 944             alive = true;
 945         }
 946         alive |= resolveBreaks(tree, prevPendingExits);
 947         nextadr = nextadrPrev;
 948     }
 949     // where
 950         /** Add any variables defined in stats to inits and uninits. */
 951         private static void addVars(List<JCStatement> stats, Bits inits,
 952                                     Bits uninits) {
 953             for (;stats.nonEmpty(); stats = stats.tail) {
 954                 JCTree stat = stats.head;
 955                 if (stat.getTag() == JCTree.VARDEF) {
 956                     int adr = ((JCVariableDecl) stat).sym.adr;
 957                     inits.excl(adr);
 958                     uninits.incl(adr);
 959                 }
 960             }
 961         }
 962 
 963     public void visitTry(JCTry tree) {










 964         List<Type> caughtPrev = caught;
 965         List<Type> thrownPrev = thrown;
 966         thrown = List.nil();
 967         for (List<JCCatch> l = tree.catchers; l.nonEmpty(); l = l.tail) {
 968             List<JCExpression> subClauses = TreeInfo.isMultiCatch(l.head) ?
 969                     ((JCTypeDisjoint)l.head.param.vartype).components :
 970                     List.of(l.head.param.vartype);
 971             for (JCExpression ct : subClauses) {
 972                 caught = chk.incl(ct.type, caught);
 973             }
 974         }
 975         Bits uninitsTryPrev = uninitsTry;
 976         ListBuffer<PendingExit> prevPendingExits = pendingExits;
 977         pendingExits = new ListBuffer<PendingExit>();
 978         Bits initsTry = inits.dup();
 979         uninitsTry = uninits.dup();







 980         scanStat(tree.body);
 981         List<Type> thrownInTry = thrown;
 982         thrown = thrownPrev;
 983         caught = caughtPrev;
 984         boolean aliveEnd = alive;
 985         uninitsTry.andSet(uninits);
 986         Bits initsEnd = inits;
 987         Bits uninitsEnd = uninits;
 988         int nextadrCatch = nextadr;
 989 












 990         List<Type> caughtInTry = List.nil();
 991         for (List<JCCatch> l = tree.catchers; l.nonEmpty(); l = l.tail) {
 992             alive = true;
 993             JCVariableDecl param = l.head.param;
 994             List<JCExpression> subClauses = TreeInfo.isMultiCatch(l.head) ?
 995                     ((JCTypeDisjoint)l.head.param.vartype).components :
 996                     List.of(l.head.param.vartype);
 997             List<Type> ctypes = List.nil();
 998             List<Type> rethrownTypes = chk.diff(thrownInTry, caughtInTry);
 999             for (JCExpression ct : subClauses) {
1000                 Type exc = ct.type;
1001                 ctypes = ctypes.append(exc);
1002                 if (types.isSameType(exc, syms.objectType))
1003                     continue;
1004                 if (chk.subset(exc, caughtInTry)) {
1005                     log.error(l.head.pos(),
1006                               "except.already.caught", exc);
1007                 } else if (!chk.isUnchecked(l.head.pos(), exc) &&
1008                            exc.tsym != syms.throwableType.tsym &&
1009                            exc.tsym != syms.exceptionType.tsym &&


1276             Bits initsWhenTrueLeft = initsWhenTrue;
1277             Bits uninitsWhenTrueLeft = uninitsWhenTrue;
1278             inits = initsWhenFalse;
1279             uninits = uninitsWhenFalse;
1280             scanCond(tree.rhs);
1281             initsWhenTrue.andSet(initsWhenTrueLeft);
1282             uninitsWhenTrue.andSet(uninitsWhenTrueLeft);
1283             break;
1284         default:
1285             scanExpr(tree.lhs);
1286             scanExpr(tree.rhs);
1287         }
1288     }
1289 
1290     public void visitAnnotatedType(JCAnnotatedType tree) {
1291         // annotations don't get scanned
1292         tree.underlyingType.accept(this);
1293     }
1294 
1295     public void visitIdent(JCIdent tree) {
1296         if (tree.sym.kind == VAR)
1297             checkInit(tree.pos(), (VarSymbol)tree.sym);












1298     }
1299 
1300     public void visitTypeCast(JCTypeCast tree) {
1301         super.visitTypeCast(tree);
1302         if (!tree.type.isErroneous()
1303             && lint.isEnabled(Lint.LintCategory.CAST)
1304             && types.isSameType(tree.expr.type, tree.clazz.type)
1305             && !(ignoreAnnotatedCasts && containsTypeAnnotation(tree.clazz))) {
1306             log.warning(tree.pos(), "redundant.cast", tree.expr.type);
1307         }
1308     }
1309 
1310     public void visitTopLevel(JCCompilationUnit tree) {
1311         // Do nothing for TopLevel since each class is visited individually
1312     }
1313 
1314 /**************************************************************************
1315  * utility methods for ignoring type-annotated casts lint checking
1316  *************************************************************************/
1317     private static final boolean ignoreAnnotatedCasts = true;




 248      */
 249     JCClassDecl classDef;
 250 
 251     /** The first variable sequence number in this class definition.
 252      */
 253     int firstadr;
 254 
 255     /** The next available variable sequence number.
 256      */
 257     int nextadr;
 258 
 259     /** The list of possibly thrown declarable exceptions.
 260      */
 261     List<Type> thrown;
 262 
 263     /** The list of exceptions that are either caught or declared to be
 264      *  thrown.
 265      */
 266     List<Type> caught;
 267 
 268     /** The list of unreferenced automatic resources.
 269      */
 270     List<Symbol> unrefdResources;
 271 
 272     /** Set when processing a loop body the second time for DU analysis. */
 273     boolean loopPassTwo = false;
 274 
 275     /*-------------------- Environments ----------------------*/
 276 
 277     /** A pending exit.  These are the statements return, break, and
 278      *  continue.  In addition, exception-throwing expressions or
 279      *  statements are put here when not known to be caught.  This
 280      *  will typically result in an error unless it is within a
 281      *  try-finally whose finally block cannot complete normally.
 282      */
 283     static class PendingExit {
 284         JCTree tree;
 285         Bits inits;
 286         Bits uninits;
 287         Type thrown;
 288         PendingExit(JCTree tree, Bits inits, Bits uninits) {
 289             this.tree = tree;
 290             this.inits = inits.dup();
 291             this.uninits = uninits.dup();


 948             alive = true;
 949         }
 950         alive |= resolveBreaks(tree, prevPendingExits);
 951         nextadr = nextadrPrev;
 952     }
 953     // where
 954         /** Add any variables defined in stats to inits and uninits. */
 955         private static void addVars(List<JCStatement> stats, Bits inits,
 956                                     Bits uninits) {
 957             for (;stats.nonEmpty(); stats = stats.tail) {
 958                 JCTree stat = stats.head;
 959                 if (stat.getTag() == JCTree.VARDEF) {
 960                     int adr = ((JCVariableDecl) stat).sym.adr;
 961                     inits.excl(adr);
 962                     uninits.incl(adr);
 963                 }
 964             }
 965         }
 966 
 967     public void visitTry(JCTry tree) {
 968         unrefdResources = List.nil();
 969         for (JCTree resource : tree.resources) {
 970             if (resource instanceof JCVariableDecl) {
 971                 visitVarDef((JCVariableDecl) resource);
 972             } else if (resource instanceof JCExpression) {
 973                 scanExpr((JCExpression) resource);
 974             } else {
 975                 throw new AssertionError(tree);  // parser error
 976             }
 977         }
 978         List<Type> caughtPrev = caught;
 979         List<Type> thrownPrev = thrown;
 980         thrown = List.nil();
 981         for (List<JCCatch> l = tree.catchers; l.nonEmpty(); l = l.tail) {
 982             List<JCExpression> subClauses = TreeInfo.isMultiCatch(l.head) ?
 983                     ((JCTypeDisjoint)l.head.param.vartype).components :
 984                     List.of(l.head.param.vartype);
 985             for (JCExpression ct : subClauses) {
 986                 caught = chk.incl(ct.type, caught);
 987             }
 988         }
 989         Bits uninitsTryPrev = uninitsTry;
 990         ListBuffer<PendingExit> prevPendingExits = pendingExits;
 991         pendingExits = new ListBuffer<PendingExit>();
 992         Bits initsTry = inits.dup();
 993         uninitsTry = uninits.dup();
 994         for (JCTree resource : tree.resources) {
 995             MethodSymbol closeMethod =
 996                         (MethodSymbol)resource.type.tsym.members().lookup(names.close).sym;
 997             for (Type thrownType : closeMethod.getThrownTypes()) {
 998                 markThrown(tree.body, thrownType);
 999             }
1000         }
1001         scanStat(tree.body);
1002         List<Type> thrownInTry = thrown;
1003         thrown = thrownPrev;
1004         caught = caughtPrev;
1005         boolean aliveEnd = alive;
1006         uninitsTry.andSet(uninits);
1007         Bits initsEnd = inits;
1008         Bits uninitsEnd = uninits;
1009         int nextadrCatch = nextadr;
1010 
1011         if (unrefdResources.nonEmpty()) {
1012             for (List<JCTree> l = tree.resources; l.nonEmpty(); l = l.tail) {
1013                 if (l.head instanceof JCVariableDecl) {
1014                     JCVariableDecl v = (JCVariableDecl) l.head;
1015                     if (unrefdResources.contains(v.sym)) {
1016                         log.warning(v.pos(),
1017                                     "automatic.resource.not.referenced", v.sym);
1018                     }
1019                 }
1020             }
1021         }
1022 
1023         List<Type> caughtInTry = List.nil();
1024         for (List<JCCatch> l = tree.catchers; l.nonEmpty(); l = l.tail) {
1025             alive = true;
1026             JCVariableDecl param = l.head.param;
1027             List<JCExpression> subClauses = TreeInfo.isMultiCatch(l.head) ?
1028                     ((JCTypeDisjoint)l.head.param.vartype).components :
1029                     List.of(l.head.param.vartype);
1030             List<Type> ctypes = List.nil();
1031             List<Type> rethrownTypes = chk.diff(thrownInTry, caughtInTry);
1032             for (JCExpression ct : subClauses) {
1033                 Type exc = ct.type;
1034                 ctypes = ctypes.append(exc);
1035                 if (types.isSameType(exc, syms.objectType))
1036                     continue;
1037                 if (chk.subset(exc, caughtInTry)) {
1038                     log.error(l.head.pos(),
1039                               "except.already.caught", exc);
1040                 } else if (!chk.isUnchecked(l.head.pos(), exc) &&
1041                            exc.tsym != syms.throwableType.tsym &&
1042                            exc.tsym != syms.exceptionType.tsym &&


1309             Bits initsWhenTrueLeft = initsWhenTrue;
1310             Bits uninitsWhenTrueLeft = uninitsWhenTrue;
1311             inits = initsWhenFalse;
1312             uninits = uninitsWhenFalse;
1313             scanCond(tree.rhs);
1314             initsWhenTrue.andSet(initsWhenTrueLeft);
1315             uninitsWhenTrue.andSet(uninitsWhenTrueLeft);
1316             break;
1317         default:
1318             scanExpr(tree.lhs);
1319             scanExpr(tree.rhs);
1320         }
1321     }
1322 
1323     public void visitAnnotatedType(JCAnnotatedType tree) {
1324         // annotations don't get scanned
1325         tree.underlyingType.accept(this);
1326     }
1327 
1328     public void visitIdent(JCIdent tree) {
1329         if (tree.sym.kind == VAR) {
1330             checkInit(tree.pos(), (VarSymbol)tree.sym);
1331             referenced(tree.sym);
1332         }
1333     }
1334 
1335     void referenced(Symbol sym) {
1336         if (unrefdResources != null && unrefdResources.contains(sym)) {
1337             ListBuffer<Symbol> lb = new ListBuffer<Symbol>();
1338             for (List<Symbol> l = unrefdResources; l.nonEmpty(); l = l.tail)
1339                 if (l.head != sym)
1340                     lb.add(l.head);
1341             unrefdResources = lb.toList();
1342         }
1343     }
1344 
1345     public void visitTypeCast(JCTypeCast tree) {
1346         super.visitTypeCast(tree);
1347         if (!tree.type.isErroneous()
1348             && lint.isEnabled(Lint.LintCategory.CAST)
1349             && types.isSameType(tree.expr.type, tree.clazz.type)
1350             && !(ignoreAnnotatedCasts && containsTypeAnnotation(tree.clazz))) {
1351             log.warning(tree.pos(), "redundant.cast", tree.expr.type);
1352         }
1353     }
1354 
1355     public void visitTopLevel(JCCompilationUnit tree) {
1356         // Do nothing for TopLevel since each class is visited individually
1357     }
1358 
1359 /**************************************************************************
1360  * utility methods for ignoring type-annotated casts lint checking
1361  *************************************************************************/
1362     private static final boolean ignoreAnnotatedCasts = true;